java .contains()来查找数组

时间:2014-03-19 02:57:41

标签: java arrays equals contains

我知道如果数组共享相同的引用,那么数组只相互相等,而且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));

应该打印出来。

4 个答案:

答案 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

myArraycheckFor是两个不同的对象,它们没有任何共同之处。

例如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;
}

不优雅,也不是最有效的方式。只是一个肮脏的黑客。