轻松更改 Java 中 Collections 接口中的 .contains() 方法以断言平等
Easily Change the .contains() method in the Collections interface in Java for Asserting Equality
我想知道是否有一种方法可以轻松修改 Java 中 List 界面中的“.contains()”方法,而无需创建自定义 class。例如:
在处理 java 中的数组集合时,.contains() 方法将始终 return false,因为 .contains() 方法始终使用通用的 .equals( ) 从对象 class 调用,如果比较的对象在内存中具有相同的引用,则只有 return 为真。但是,对于数组,对两个数组执行 Arrays.equals() 检查会更有用。
代码:
public class Temp {
public static void main(String[] args) {
int[] myIntArray = new int[] {1, 2, 3};
List<int[]> myList = new ArrayList<>();
myList.add(myIntArray);
System.out.println(myList.contains(new int[] {1, 2, 3}));
} // Output in the console: false
// Preferred output: true
}
我知道可以通过使用 for 循环并使用 Arrays.equals() 方法遍历整个列表来轻松完成此操作,但我的目标是学习如何轻松雕刻.contains() 方法放入我需要的东西以备将来使用。非常感谢!
I am wondering if there is a way to easily modify the contains
method in the List
interface in Java without creating a custom class.
没有办法。 List
的标准实现的 contains
方法的行为与 List
API 指定的一样;即他们使用 equals
方法。
另一方面,不难扩展 ArrayList
class 并覆盖 contains
来做你想做的事。但是如果你做得对,你需要考虑你是否想要:
indexOf
和 lastIndexOf
与 contains
保持一致
equals(Object)
的语义要与之一致
sublist(int, int)
返回列表的语义与主列表的语义一致。
没有。 contains()
除了使用 Object.equals
之外不能做任何事情,因为这是规范所要求的。
这并不是说想要包含数组的概念是不合理的;只是你不能超载现有的概念。
你可以直接创建一个静态方法:
static <T> boolean containsArray(List<? extends T[]> list, T[] query) {
return list.stream().anyMatch(e -> Arrays.equals(e, query));
}
然后在您要调用 list.contains(query)
.
的地方调用它
它的优点是适用于 any 列表(带有引用类型的数组元素):您不必专门创建它,只需更新这些专门的比较。
(以上适用于任何引用类型的数组。您需要将其专门用于原始类型的数组)。
它的另一个优点是您不必处理 强调的棘手后果(例如 indexOf
、remove
等如何工作)。
还有另一种选择:使用支持等于 "correctly" 的列表元素类型。例如,您可以使用 Arrays.asList
包装数组以将它们存储在列表中,因此您有一个 List<List<T>>
而不是 List<T[]>
.
这将是一个侵入性的更改:它需要更改整个代码中列表的类型;你没有提供任何迹象表明你的数组列表是如何被广泛使用的。
我想知道是否有一种方法可以轻松修改 Java 中 List 界面中的“.contains()”方法,而无需创建自定义 class。例如:
在处理 java 中的数组集合时,.contains() 方法将始终 return false,因为 .contains() 方法始终使用通用的 .equals( ) 从对象 class 调用,如果比较的对象在内存中具有相同的引用,则只有 return 为真。但是,对于数组,对两个数组执行 Arrays.equals() 检查会更有用。
代码:
public class Temp {
public static void main(String[] args) {
int[] myIntArray = new int[] {1, 2, 3};
List<int[]> myList = new ArrayList<>();
myList.add(myIntArray);
System.out.println(myList.contains(new int[] {1, 2, 3}));
} // Output in the console: false
// Preferred output: true
}
我知道可以通过使用 for 循环并使用 Arrays.equals() 方法遍历整个列表来轻松完成此操作,但我的目标是学习如何轻松雕刻.contains() 方法放入我需要的东西以备将来使用。非常感谢!
I am wondering if there is a way to easily modify the
contains
method in theList
interface in Java without creating a custom class.
没有办法。 List
的标准实现的 contains
方法的行为与 List
API 指定的一样;即他们使用 equals
方法。
另一方面,不难扩展 ArrayList
class 并覆盖 contains
来做你想做的事。但是如果你做得对,你需要考虑你是否想要:
indexOf
和lastIndexOf
与contains
保持一致
equals(Object)
的语义要与之一致sublist(int, int)
返回列表的语义与主列表的语义一致。
没有。 contains()
除了使用 Object.equals
之外不能做任何事情,因为这是规范所要求的。
这并不是说想要包含数组的概念是不合理的;只是你不能超载现有的概念。
你可以直接创建一个静态方法:
static <T> boolean containsArray(List<? extends T[]> list, T[] query) {
return list.stream().anyMatch(e -> Arrays.equals(e, query));
}
然后在您要调用 list.contains(query)
.
它的优点是适用于 any 列表(带有引用类型的数组元素):您不必专门创建它,只需更新这些专门的比较。
(以上适用于任何引用类型的数组。您需要将其专门用于原始类型的数组)。
它的另一个优点是您不必处理 indexOf
、remove
等如何工作)。
还有另一种选择:使用支持等于 "correctly" 的列表元素类型。例如,您可以使用 Arrays.asList
包装数组以将它们存储在列表中,因此您有一个 List<List<T>>
而不是 List<T[]>
.
这将是一个侵入性的更改:它需要更改整个代码中列表的类型;你没有提供任何迹象表明你的数组列表是如何被广泛使用的。