1

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?

WJS
  • 36,363
  • 4
  • 24
  • 39
Aakash Patel
  • 549
  • 5
  • 19
  • Does this answer your question? [How do I remove repeated elements from ArrayList?](https://stackoverflow.com/questions/203984/how-do-i-remove-repeated-elements-from-arraylist) – Hulk Apr 19 '22 at 11:55
  • possible dupliate https://stackoverflow.com/questions/13912004/remove-duplicates-from-integer-array – Ravindra Kumar Apr 19 '22 at 11:56
  • @Ravindra not duplicate because lists are not hashable. – Jhanzaib Humayun Apr 19 '22 at 11:58
  • Just note: conceptually it isn't great to mix two different concepts. Either use arrays, or use Collection interfaces/classes. Prefer a List of List, not a List of Array. And when you do that, you get the "expected" behavior out of the box, as two lists are equal when their entries are equal, which means you just push them into a Set to remove the duplicate entries. – GhostCat Apr 19 '22 at 12:06
  • Hi @hulk that question does not answer the question because In my case it is List which means i have to make sure that in the list there is no duplicate array. If it was string, it would have been easy. or even any array of object, it was easy due to euqls and hashcode mathod. But it is Integer[], which is the problem here – Aakash Patel Apr 19 '22 at 12:13
  • @AakashPatel Ok agreed, none of the top answers there handels this case. – Hulk Apr 19 '22 at 12:28

2 Answers2

2

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.

WJS
  • 36,363
  • 4
  • 24
  • 39
1

If you want to maintain the order of the entries in the original list and the original list is mutable, you can also use List.removeIf:

Comparator<Integer[]> comp = (a,b)->Arrays.compare(a,b);
Set<Integer[]> set = new TreeSet<>(comp); 
yourList.removeIf(x -> !set.add(x));

(based on a comment by Holger on an answer to a related question)

Hulk
  • 6,399
  • 1
  • 30
  • 52