如何覆盖数组的 equals 方法?
How do I override the equals method of an array?
Set 和 List 之间的主要区别是 Set 不允许重复。因此,我试图创建一个 Set<Integer[]>
而不是 List<Integer[]>
,这样没有两个元素是相等的。但是当我阅读 Set<Integer[]>
时,我得到了以下结果
[0, 4, 5]
[3, 4, 1]
[4, 5, 0]
[0, 3, 6]
[1, 3, 4]
[1, 2, 7]
对于我的实现,[0, 4, 5]
和 [4, 5, 0]
被认为是相等的。因此我的问题是:有没有办法覆盖 Integer[]
的 equals 方法,以便 set 函数的 add
方法可以避免同时接受 [0, 4, 5]
和 [4, 5, 0]
?
您不能覆盖数组中的任何方法。但是您并不是要覆盖数组中的方法,您真正想做的是防止 Set
.
中的重复项
因此,正如@nneonneo 所建议的,正确的做法是使用数组以外的东西。数组 固有地对其元素 有顺序,这意味着您正在努力使用 Set<Integer[]>
进行艰苦的战斗。您有三个更好的选择:
- 使用没有固有顺序的数据结构,例如
HashSet
- 使用保留固有顺序的数据结构,例如
TreeSet
or TreeMultiset
in Guava
- 使用覆盖
.equals()
比较的自定义对象,即 wraps 数组。
然后,您的目标集将分别是 Set<Set<Integer>>
或 Set<Multiset<Integer>>
或 Set<MyWrapper>
。
出于性能原因,我建议反对 使用未排序数组 的自定义Comparator
作为您的Set
。排序的数据结构可以在 O(n) Integer
比较中进行相等比较,但在原始情况下,未排序的数据结构至少需要 O(n log n)。但是,如果出于某种原因必须使用数组,该解决方案将起作用。这就是我上面"uphill battle"的意思。
将 java.util.TreeSet 与比较器一起使用,对于您认为相等的两个数组 returns 零,否则遵循任何一致的排序规则。
根据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."
简答:你不能。根本没有机制可以覆盖数组 class 中的任何内容。
相反,请考虑为您的对象使用替代容器。您可以为对象使用 Set<Integer>
,创建 Set<Set<Integer>>
,因为您似乎想要进行无序比较。
或者,为了获得更精细的控制,请考虑使用您自己的 class 来包装数组或集合,例如Set<MyIntegerBag>
。然后您将完全控制所使用的比较操作。
完全比较两个数组的一种方法是使用方法:
Integer[]arrayOne, arrayTwo;
//Arrays get set with contents, etc.
Arrays.equals(arrayOne, array2);
equals 方法按顺序比较每个项目以及数组的大小。
这来自一个类似的问题:How to overide equals for array in Java? 在那个例子中,他们使用了采用原始数组类型的方法,但您可以使用采用 Object[] 的方法。
Set 和 List 之间的主要区别是 Set 不允许重复。因此,我试图创建一个 Set<Integer[]>
而不是 List<Integer[]>
,这样没有两个元素是相等的。但是当我阅读 Set<Integer[]>
[0, 4, 5]
[3, 4, 1]
[4, 5, 0]
[0, 3, 6]
[1, 3, 4]
[1, 2, 7]
对于我的实现,[0, 4, 5]
和 [4, 5, 0]
被认为是相等的。因此我的问题是:有没有办法覆盖 Integer[]
的 equals 方法,以便 set 函数的 add
方法可以避免同时接受 [0, 4, 5]
和 [4, 5, 0]
?
您不能覆盖数组中的任何方法。但是您并不是要覆盖数组中的方法,您真正想做的是防止 Set
.
因此,正如@nneonneo 所建议的,正确的做法是使用数组以外的东西。数组 固有地对其元素 有顺序,这意味着您正在努力使用 Set<Integer[]>
进行艰苦的战斗。您有三个更好的选择:
- 使用没有固有顺序的数据结构,例如
HashSet
- 使用保留固有顺序的数据结构,例如
TreeSet
orTreeMultiset
in Guava - 使用覆盖
.equals()
比较的自定义对象,即 wraps 数组。
然后,您的目标集将分别是 Set<Set<Integer>>
或 Set<Multiset<Integer>>
或 Set<MyWrapper>
。
出于性能原因,我建议反对 使用未排序数组 的自定义Comparator
作为您的Set
。排序的数据结构可以在 O(n) Integer
比较中进行相等比较,但在原始情况下,未排序的数据结构至少需要 O(n log n)。但是,如果出于某种原因必须使用数组,该解决方案将起作用。这就是我上面"uphill battle"的意思。
将 java.util.TreeSet 与比较器一起使用,对于您认为相等的两个数组 returns 零,否则遵循任何一致的排序规则。
根据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."
简答:你不能。根本没有机制可以覆盖数组 class 中的任何内容。
相反,请考虑为您的对象使用替代容器。您可以为对象使用 Set<Integer>
,创建 Set<Set<Integer>>
,因为您似乎想要进行无序比较。
或者,为了获得更精细的控制,请考虑使用您自己的 class 来包装数组或集合,例如Set<MyIntegerBag>
。然后您将完全控制所使用的比较操作。
完全比较两个数组的一种方法是使用方法:
Integer[]arrayOne, arrayTwo;
//Arrays get set with contents, etc.
Arrays.equals(arrayOne, array2);
equals 方法按顺序比较每个项目以及数组的大小。
这来自一个类似的问题:How to overide equals for array in Java? 在那个例子中,他们使用了采用原始数组类型的方法,但您可以使用采用 Object[] 的方法。