41

Possible Duplicate:
Java: Checking equality of arrays (order doesnt matter)

I have two arrays :

String[] a1 = {"a", "b", "c"};
String[] a2 = {"c", "b", "a"};

I need to check if both contains same elements (and of same length) irrespective of order of elements.

I tried Arrays.equals(a1, a2) but it considers order of element. org.apache.commons.lang.ArrayUtils does not provide this thing.

I know I can achieve the same by creating my own method (checking for same length, then sorting both array and then using Arrays.equals(a1, a2)) but wanted to know if this thing is provided in any API or there is more smart way to do the same.

Community
  • 1
  • 1
Anil Bharadia
  • 2,760
  • 6
  • 34
  • 46

4 Answers4

35

If you have these arrays in something inheriting from Collection, you can just use collection.containsAll( otherCollection ) from the Collection interface. However, you'll also need to compare the lengths of the two to verify that one set isn't a superset of the other.

(Thanks go to Aardvarkk and piegames.)

http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#containsAll(java.util.Collection)

Note: This will work up to a point. This is defined to check for at least one of any element existing. That is, if you have 3 a values in one collection, and 7 a values in the other, that will not necessarily cause it to call them unequal.

Examples:

[a, b, c] == [c, a, b]             // Works -- Mixed order
[a, b, c, d, d] == [a, b, d, c, d] // Works -- Mixed order with repeats
[a, b, c, d, d] == [a, b, b, c, d] // FAILS -- Different repeats
[a, b, c, d, d] != [a, b, c, d]    // Works -- Length differs with repeats
[a, b, c, d] != [a, b, c]          // Works -- Length differs
[a, b, d] != [a, b, c]             // Works -- Disjoint sets
BlackVegetable
  • 12,594
  • 8
  • 50
  • 82
  • 10
    Wouldn't you need to check containsAll in both directions? A one-way evaluation would return true for a set which was a superset of the other, which doesn't appear to be what the OP wants. – aardvarkk Aug 17 '12 at 16:21
  • @aardvarkk Excellent point! I'll edit my post. – BlackVegetable Aug 17 '12 at 16:26
  • 4
    This doesn't handle duplicates correctly. The JavaDoc doesn't make this clear, but `a.containsAll(b)` iff `a` contains **at least one** `x` for each element `x` in `b`. As an example, try testing with `a={5}`, `b={5,5}`. They're not equal when viewed as multisets, but `containsAll` returns `true` in both directions. – Daniel Lubarov Nov 14 '13 at 01:31
  • At least this is the interpretation of `containsAll` that's used in practice. Even Guava's [Multiset.containsAll](http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multiset.html#containsAll) "does not take into account the occurrence count of an element". – Daniel Lubarov Nov 14 '13 at 01:35
  • @Daniel Right, this was covered by the portion of my answer labeled "Note". – BlackVegetable Nov 14 '13 at 02:26
  • 2
    @aardvarkk Wouldn't it be enough to just check the length of both Arrays instead of the second containsAll? (Assuming there are no duplicates) – piegames Sep 03 '16 at 09:17
  • @piegames That's absolutely correct. I'm a little embarrassed I didn't think of that. I will update this answer. – BlackVegetable Sep 03 '16 at 13:20
28

i think it may work for you, sort first array with

Arrays.sort(Object[]);

and after that you can compare with

Arrays.equals(Object[],Object[]);

complete code is:

String[] a1 = {"a", "b", "c"};
String[] a2 = {"c", "b", "a"};
Arrays.sort(a2);

boolean result= Arrays.equals(a1, a2);
satvinder singh
  • 1,152
  • 1
  • 12
  • 22
15

Convert the lists to sets before comparing them :

new HashSet( Arrays.asList( a1 )).equals( new HashSet( Arrays.asList( a2 ) ));

Alternatively, you can sort the arrays using Arrays.sort() but that might break code which depends on the order of the elements in the arrays.

Wandang
  • 912
  • 2
  • 8
  • 37
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
2

Use java.util.Set method equals. Compares two sets have the same size, and every member of the specified set is contained in other set.

Roman C
  • 49,761
  • 33
  • 66
  • 176