2

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!

12
  • Do you want to set the reference to null or remove them? A simpler way of doing this is to have a Set<List<Integer>> which will implicitly drop any duplicates. Do you want to remove duplicate rows or values? Commented Nov 1, 2016 at 17:02
  • Lets say the first list in table holds integer Integer(1), and third list also holds such an object: do you want to null both objects or only objects that follow the first "unique" one? Commented Nov 1, 2016 at 17:02
  • Do you want to keep the table the same size? Same number of rows and entries per row? Commented Nov 1, 2016 at 17:03
  • @PeterLawrey how is the hashvalue for List<Integer> computed and compared in between List<Integer> members of the Set? E.g., how will a set { [1, 3], [1, 4] } define what duplicate inner list values are? (Pardon the syntax, I'm just getting started with Java, asking out of curiosity!) Commented Nov 1, 2016 at 17:05
  • 1
    @PeterLawrey Added example how this must work:/ Commented Nov 1, 2016 at 17:08

3 Answers 3

2

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));
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.