Reputation: 23
I got table like
List<List<Integer>> table = new ArrayList<>()
Where List's within are table rows, i need to set all duplicate values ALL OVER THE TABLE to null, how can do it via only ArrayList && foreach loop || λ - expressions?
Must work somehow like this:
1 2 3 null 2 3
4 1 5 -> 4 null 5
1 6 9 null 6 9
Sorry for my poor English and thank you for fast response!
Upvotes: 2
Views: 131
Reputation: 12817
Try this, this approach is to build an index map for all the elements present in the List
and setting the value to null
if more than one value found for a key
List<List<Integer>> table = new ArrayList<>();
table.add(Arrays.asList(1, 2, 3));
table.add(Arrays.asList(4, 1, 5));
table.add(Arrays.asList(1, 6, 9));
System.out.println("Before " + table);
Map<Integer, List<List<Integer>>> indices = new HashMap<>();
for (int i = 0; i < table.size(); i++) {
for (int j = 0; j < table.get(i).size(); j++) {
int el = table.get(i).get(j);
if (indices.get(el) == null) {
indices.put(el, new ArrayList<>());
}
indices.get(el).add(Arrays.asList(i, j));
}
}
indices.keySet().stream()
.filter(k -> indices.get(k).size() > 1)
.flatMap(k -> indices.get(k).stream())
.forEach(li -> table.get(li.get(0)).set(li.get(1), null));
System.out.println("After " + table);
output
Before [[1, 2, 3], [4, 1, 5], [1, 6, 9]]
After [[null, 2, 3], [4, null, 5], [null, 6, 9]]
Upvotes: 0
Reputation: 425198
Interpreting the (slightly unclear) question as a deduplication (removal rather than "nulling"):
List<List<Integer>> dedup = table.stream().distinct().collect(toList());
or java 7:
List<List<Integer>> dedup = new ArrayList<>(new LinkedHashSet<>(table));
which is generally more useful.
However, if nulling is really required:
Set<List<Integer>> set = new HashSet<>();
List<List<Integer>> dedup = table.stream()
.filter(list -> set.add(list) ? list : null)
.collect(toList());
The add()
method of a Set returns true
is adding the element changed the set - ie if it's an element not seen before.
Upvotes: 0
Reputation: 2523
Using java-8,
//Find duplicates
Map<Integer, Long> counts =
table.stream()
.flatMap(Collection::stream)
.collect(Collectors.groupingBy(i->i, Collectors.counting()));
// and remove them
table.stream().forEach(row -> row.replaceAll(i-> counts.get(i) > 1 ? null : i));
Upvotes: 2