Search code examples
javaarraysunique

How to get unique list of array?


I have List of Integer arrays

Integer[] i1 = new Integer[2]; i1[0] = 1; i1[1] = 1;
Integer[] i2 = new Integer[2]; i2[0] = 1; i2[1] = 1;
Integer[] i3 = new Integer[2]; i3[0] = 0; i3[1] = 0;

List<Integer[] arrayList = new ArrayList<>();
arrayList.add(i1);
arrayList.add(i2);
arrayList.add(i3); 

How can I remove duplicate array i2 from that list?


Solution

  • Regular sets do not check for equality of Arrays. So you can't depend on the duplicate Array to be removed.

    Integer[] i1 = new Integer[2]; i1[0] = 1; i1[1] = 1;
    Integer[] i2 = new Integer[2]; i2[0] = 1; i2[1] = 1;
    Integer[] i3 = new Integer[2]; i3[0] = 0; i3[1] = 0;
    
    List<Integer[]> list1   = List.of(i1,i2,i3);
    Set<Integer[]> set = new HashSet<>();
    set.addAll(list1);
    set.forEach(arr->System.out.println(Arrays.toString(arr)));
    

    prints

    [0, 0]
    [1, 1]
    [1, 1]
    

    But you can do it like so.

    • define a comparator for a TreeSet and use that for duplicate detection in the Array.
    Comparator<Integer[]> comp = (a,b)->Arrays.compare(a,b);
    
    Set<Integer[]> set = new TreeSet<>(comp);
    set.addAll(list1);
    set.forEach(a->System.out.println(Arrays.toString(a));
    

    prints

    [0, 0]
    [1, 1]
    
    

    Note that the order of the arrays in the set may change from what they were in the list. To preserve the encounter order you can use a stateful filter which records checks to see if the Array has already been seen.

    Set<Integer[]> seen = new TreeSet<>((a, b) -> Arrays.compare(a, b));
    List<Integer[]> result =
            list1.stream().filter(seen::add).toList();
    

    NOTE: This should only be used in sequential streams. Parallel operations may result in race conditions giving inaccurate results.