1

A main difference between a Set and a List is that the set admits no duplicates. So instead of List<Integer[]> I am trying to create a Set<Integer[]> such that no two elements are equal. But I am getting the following results when I read Set<Integer[]>

[0, 4, 5]
[3, 4, 1]
[4, 5, 0]
[0, 3, 6]
[1, 3, 4]
[1, 2, 7]

For my implementation, [0, 4, 5] and [4, 5, 0] are considered equal. Hence my question: Is there a way to override the equals method of Integer[] so that the add method of the set function can avoid admitting both [0, 4, 5] and [4, 5, 0]?

durron597
  • 31,968
  • 17
  • 99
  • 158
Katedral Pillon
  • 14,534
  • 25
  • 99
  • 199
  • 5
    Why don't you use a `Set>` or somesuch? Or, `Set`? Are you tied to `Integer[]` for any reason? – nneonneo Jul 14 '15 at 16:31
  • 4
    And no, you **cannot** override `equals` for an array. – nneonneo Jul 14 '15 at 16:31
  • There's a similar question with an answer at: http://stackoverflow.com/questions/12292513/how-to-overide-equals-for-array-in-java In that example they used the primitive type, but you can use the method that takes the Object[] arrays. – lordoku Jul 14 '15 at 16:35
  • I can add a response, although it looks like a better one has come up – lordoku Jul 14 '15 at 19:27

4 Answers4

6

You cannot override any methods in arrays. But you're not trying to override methods in arrays, what you're really trying to do is prevent duplicates in your Set.

Therefore, as @nneonneo suggests, the right thing to do is use something other than an array. Arrays inherently have order to their elements, which means you're fighting an uphill battle trying to use Set<Integer[]>. You have three better options:

  1. Use a data structure that doesn't have inherent order, such as HashSet
  2. Use a data structure that does preserve inherent order, such as TreeSet or TreeMultiset in Guava
  3. Use a custom object that overrides the .equals() comparison for you, that wraps the array.

Then, your target set would be a Set<Set<Integer>> or a Set<Multiset<Integer>> or a Set<MyWrapper> in each case, respectively.


I recommend against using a custom Comparator of unsorted arrays for your Set for performance reasons. A sorted data structure can do the equality comparison in O(n) Integer comparisons, but an unsorted one will need at least O(n log n) in the naive case. However, that solution will work if you must use an array for some reason. This is what I meant by "uphill battle" above.

Community
  • 1
  • 1
durron597
  • 31,968
  • 17
  • 99
  • 158
  • When you recommend against using a custom `Comparator`, I'm guessing from context that you are implicitly referring to a custom Comparator *of unsorted arrays.* – Andy Thomas Jul 14 '15 at 16:56
6

Short answer: you can't. There's no mechanism to override anything in an array class at all.

Instead, please consider using an alternative container for your objects. You could use a Set<Integer> for the objects, creating a Set<Set<Integer>>, since it seems you want to do order-less comparisons.

Or, for more fine-tuned control, consider using your own class that wraps an array or set and having e.g. Set<MyIntegerBag>. Then you will have full control over the comparison operation that is used.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
3

Use java.util.TreeSet with a Comparator that returns zero for two arrays you consider equal, and otherwise follows any consistent ordering rule.

According to the TreeSet documentation, "a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface."

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
0

One way to completely compare against two arrays is to use the method:

Integer[]arrayOne, arrayTwo;
//Arrays get set with contents, etc. 
Arrays.equals(arrayOne, array2);

The equals method compares each item, in order, as well as the size of the array.

This came from a similarly asked question: How to overide equals for array in Java? In that example, they used the method that took the primitive array types, but you can use the method that takes in Object[].

Community
  • 1
  • 1
lordoku
  • 908
  • 8
  • 22