-2

I want to detect a duplicate in a list of list. For example

[[-1,0,-1][0,1,2][0,-1,-1]]

By duplicate, I meant if a list contains the same elements in any order.

I tried one solution which is to sort the list and insert each of them into the set. Is there any other better way to do it?

One problem I faced is, if I insert the list as it is without sorting, into a set, It'll not be detected as a duplicate. (i.e [-1,0,-1] and [0,-1,-1])

Finally how I want the list is,

[[-1,0,-1][0,1,2]]

Please note that the same question is answered here Java: Best way to remove duplicated list in a list, but it is slightly different than what I am asking here.

  • I'm not sure how set equality works, but I'd think that if you built two sets with the same three numbers in each, they'd be equal. Order definitely doesn't matter in an normal (unsorted) set. - I just tried this. If you build two sets, add -1 first to one and then 0, and add 0 first and then -1 to the other, `set1.equals(set2) == true` – CryptoFool Apr 03 '19 at 05:32
  • By definition of List.equals() the two lists will be equal if they contain same elements in the same order. Hence when you insert the ArrayLists into the set, the array list comparison will kick in and it will not be detected as duplicate. So you need to sort and the insert into Set – Hari Prasad Apr 03 '19 at 05:40
  • `HashSet tmp = new HashSet<>(); listOfList.removeIf(list -> !tmp.add(new HashSet<>(list)));` – Holger Apr 03 '19 at 11:11

2 Answers2

0

I don't know if this is a GOOD way to do this, but I went ahead and coded up your idea of using sets to look for duplicate lists. It works fine:

class Test {

    public static void main(String[] args) {

        List<List<Integer>> input = (List<List<Integer>>)JsonEncodeDecode.decode("[[-1,0,-1],[0,1,2],[0,-1,-1]]");

        List<List<Integer>> result = new ArrayList<>();
        List<Set<Integer>> sets = new ArrayList<>();
        for (List<Integer> sublist : input) {
            Set<Integer> set = new HashSet<>(sublist);
            if (!sets.contains(set)) {
                sets.add(set);
                result.add(sublist);
            }
        }
        System.out.println(JsonEncodeDecode.encode(result));
    }
}

Output:

[[-1,0,-1],[0,1,2]]

JsonEncodeDecode is my own utility class, so you won't be able to run this without doing something else to encode/decode JSON. It's just my way of building structures and printing them.

CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • One thing about this that maybe you don't want is that the lists [-1, -1, 0] and [-1, 0, 0] are also seen as the same, because the set representation doesn't retain how many of each number was in the original list. – CryptoFool Apr 03 '19 at 06:10
  • You should change `sets` to `Set> sets = new HashSet<>();`. Then, its not only more efficient, you can simplify the loop body to `if(sets.add(new HashSet<>(sublist))) result.add(sublist);` – Holger Apr 03 '19 at 11:16
  • Got it, Thanks @Steve. – Avinash MV Apr 04 '19 at 06:39
0

you can play with this Java8 feature, this will give you matched list from one to another.

list.stream().allMatch(num -> matchingList.contains(num))

Ashish Dadhich
  • 4,737
  • 4
  • 17
  • 25