JKeyS
JKeyS

Reputation: 23

Delete duplicates from table (List<List<Integer>> table = new ArrayList ...)

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

Answers (3)

Saravana
Saravana

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

Bohemian
Bohemian

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

bradimus
bradimus

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

Related Questions