【问题标题】:java .contains() to look for an arrayjava .contains() 查找数组
【发布时间】:2014-04-25 01:48:34
【问题描述】:

我知道数组只有在共享相同引用时才彼此相等,而且 deepEquals 可以检查实际值的相等性。如果我有一个数组列表,例如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));

应该打印出来是真的。

【问题讨论】:

  • 我认为您需要了解哈希码的工作原理...试试这个System.out.println(myArray == checkFor);
  • 我还很新,所以我对它们做的不多。结果是假的,这是有道理的
  • 这就是contains 正在做的事情......
  • 是的哈哈,这就是我问这个问题的原因。我知道问题是什么,只是不知道如何解决

标签: java arrays equals contains


【解决方案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&lt;Data&gt;,它的contains() 将正常运行。

另一种选择是不使用List.contains(),而是实现自己的检查方法,例如:

static boolean containsArray (List<int[]> haystack, int[] needle) {
    for (int[] item : haystack)
        if (Arrays.equals(item, needle))
            return true; 
    return false;
}

【讨论】:

    【解决方案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;
    }
    

    【讨论】:

    • 如果只有第一个元素匹配,则返回 true。你可能是指if (!deepEquals(...)) { return false; },然后是return true;,如果它通过的话。此外,您应该在迭代之前测试数组长度。
    • 如果第一个元素不匹配,它什么也不做。它循环直到 deepequals 返回 true。如果它从不返回 true,它将退出循环(当列表被迭代时)然后返回 false。这将起作用。虽然不知道应该是size还是length还是size()还是length(),我总是忘记。
    • 您可以将Arrays.equals() 用于deepEquals()
    【解决方案3】:

    问题是,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;
    
        }
    
    }
    

    【讨论】:

      【解决方案4】:

      这有点骇人听闻,但是...

      仅因为您正在处理 int[],这将起作用(即使两者都为 null)

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

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

      【讨论】:

      • Arrays.equals 没有任何问题,只是提出的问题涉及 int[] 而不是 Integer[]
      • 对不起,我以为你在说 deepEquals()
      • 我还看了deepEquals ;)
      猜你喜欢
      • 1970-01-01
      • 2015-05-04
      • 1970-01-01
      • 2021-07-07
      • 2019-07-29
      • 2015-05-13
      • 2011-04-26
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多