我知道如果数组共享相同的引用,那么数组只相互相等,而且deepEquals可以检查实际的数值&#39;平等。如果我有一个数组列表,例如List<int[]> visited
,我如何使用类似于deepEquals的东西来检查visited
是否包含我指定的数组?
例如:
List<int[]> visited = new ArrayList<int[]>();
int[] myArray = {2, 1};
visited.add(myArray);
int[] checkFor = {2, 1};
System.out.println(visited.contains(checkFor));
应该打印出来。
答案 0 :(得分:2)
private static boolean containsArray(List<int[]> list, int[] expected) {
for(int i=0; i<list.size; i++) {
if(deepEquals(list[i], expected) {
return true;
}
}
return false;
}
答案 1 :(得分:1)
问题是,ArrayList#containts
正在使用Object#equals
,其默认操作类似于this == obj
myArray
和checkFor
是两个不同的对象,它们没有任何共同之处。
例如System.out.println(myArray == checkFor);
将打印出false
。您可以通过执行以下操作来进一步测试...
checkFor[1] = 3;
System.out.println(Arrays.toString(myArray));
System.out.println(Arrays.toString(checkFor));
将输出:
[2, 1]
[2, 3]
很明显,两个阵列没有任何共同点,因此在任何方面都不相同......
...然而
System.out.println(visited.contains(myArray));
输出true
或
int[] myArray = {2, 1};
visited.add(myArray);
int[] checkFor = myArray;
System.out.println(visited.contains(checkFor));
输出true
...
您也可以使用Arrays.equals(myArray, checkFor)
关于我知道您可以完成这项工作的唯一方法,就是迭代List
并使用Arrays.equals
,例如......
public class TestArrayCollection {
public static void main(String[] args) {
List<int[]> visited = new ArrayList<int[]>();
int[] myArray = {2, 1};
visited.add(myArray);
int[] checkFor = {2, 1};
System.out.println(contains(visited, checkFor));
}
public static boolean contains(List<int[]> values, int[] match) {
boolean contains = false;
for (int[] element : values) {
if (Arrays.equals(element, match)) {
contains = true;
break;
}
}
return contains;
}
}
答案 2 :(得分:1)
您尝试使用的方法无法产生正确的结果。来自List.contains()
:
当且仅当此列表包含至少一个元素e((o==null ? e==null : o.equals(e))
)时,才返回true
然而,int[].equals(int[])
is equivalent to ==
,这不是你想要的(你想要像Arrays.equals()
这样的行为。)
你有几个选择。如果您的代码是灵活的,一个选项是创建一个包含数组的简单类,并实现其equals()
方法以测试相等性(还考虑覆盖hashCode()
并可能实现Comparable
),例如:
static class Data {
int[] array;
@Override public boolean equals (Object other) {
if (other == null || !(other instanceof Data))
return false;
else
return Arrays.equals(array, ((Data)other).array);
}
}
现在,您可以使用List<Data>
,其contains()
的行为也会恰当。
另一种选择是不使用List.contains()
,而是实施自己的方法来检查,例如:
static boolean containsArray (List<int[]> haystack, int[] needle) {
for (int[] item : haystack)
if (Arrays.equals(item, needle))
return true;
return false;
}
答案 3 :(得分:0)
这有点像hacky,但是......
只是因为你正在处理int [],这将起作用(即使两者都为空)
public static void main(String[] args) {
List<int[]> visited = new ArrayList<int[]>();
int[] myArray = {2, 1};
visited.add(myArray);
int[] checkFor = {2, 1};
System.out.println(contains(visited,checkFor));
}
private static boolean contains(List<int[]> visited, int[] checkFor) {
for(int[] i:visited){
if (Arrays.toString(i).equals(Arrays.toString(checkFor))){
return true;
}
}
return false;
}
不优雅,也不是最有效的方式。只是一个肮脏的黑客。