【问题标题】:Checking if an Integer Array exists in an Array with Integer Arrays as elements. [Java]检查整数数组是否存在于以整数数组为元素的数组中。 [爪哇]
【发布时间】:2015-02-07 20:36:26
【问题描述】:
public static int Obstacle[][] = {{1, 3}, {2, 2}};

public static boolean testerFunction(int j, int k) {
    int check[] = {j, k};
    if (Arrays.asList(Obstacle).contains(check)) {
        return true;
    }
    else {
        return false;
    }
}

我有这个代码。

它总是返回 false,尽管检查等于 {1,3} 或 {2,2}

我的代码有什么问题? Java中如何检查数组是否存在于数组数组中?

【问题讨论】:

    标签: java arrays object


    【解决方案1】:

    您正在检查引用相等而不是对象相等。请参阅下面的使用Arrays.equals 进行对象相等性检查。

    int[] a1 = { 1, 2 };
    int[] a2 = { 1, 2 };
    System.out.println(a1 == a2); // false (two different instances)
    System.out.println(Arrays.equals(a1, a2)); // true (instances are logically equal)
    

    也考虑这个测试:

    System.out.println(a1.equals(a2)); // false
    

    对于 Java 中的大多数对象,这应该返回 true,因为 a1a2 在逻辑上是相等的。但是,Array 不会覆盖 Object.equals(),因此它会退回到默认的引用相等检查 ==。这就是您的测试if (Arrays.asList(Obstacle).contains(check)) 未通过的根本原因。 Collections.contains() 使用 Object.equals 比较数组。这就是我们必须手动遍历外部数组的原因,如下所示:

    public static int[][] obstacle = { { 1, 3 }, { 2, 2 } };
    
    public static boolean testerFunction(int j, int k) {
      int[] check = { j, k };
      for (int[] a : obstacle) {
        if (Arrays.equals(a, check)) {
          return true;
        }
      }
      return false;
    }
    
    public static void main(String[] args) {
      System.out.println(testerFunction(1, 3)); // true
      System.out.println(testerFunction(2, 2)); // true
      System.out.println(testerFunction(0, 0)); // false
    }
    

    【讨论】:

    • 你的意思是引用相等吗?因为实例和对象完全一样!
    • 我解释了我的意思,如果这些术语对你来说是模棱两可的,诚然他们可以。我会将它编辑到“参考质量”,因为这是 JLS 使用的,尽管快速的网络搜索会显示“实例相等”通常用于表示同一事物,“值相等”用作同义词“对象平等”。如果我必须在这里重新定义约定,我想我会将术语更改为“对象相等”与“对象相等”。本质上,您会被问到“这个对象是 SAME 对象吗”与“这个对象是 EQUIVALENT 对象吗”。
    • 按照同样的思路,我敢打赌,如果Object.equals() 被命名为Object.isEquivalentTo(),它可能会让新手的事情变得更容易......尽管另一方面它的可读性较差。
    • Arrays.equals(...) 不是对象相等,或者任何东西。这是一个以两个数组作为输入的静态实用方法。
    • 这个答案是正确的,但我认为应该为 OP 的利益解释更多细节。原始代码失败是因为尽管Collection#contains() 使用equals(...) 比较元素,但数组不会覆盖equals(...)。您可以将此行添加到您的第一个代码示例中:System.out.println(a1.equals(a2)); // false (default equals method tests reference equality, not logical equality)
    【解决方案2】:

    您的代码的问题在于,虽然数组元素可能是等价的,但封闭的数组却不是。

    考虑以下示例:

    int[] a = {1, 2, 3}
    int[] b = {1, 2, 3}
    
    System.out.println(a == b); //Prints false
    

    虽然数组 ab 都包含元素 1、2 和 3,但它们在功能上是不同的数组,占用不同的内存空间。

    实现您想要的唯一方法是通过手动循环、取消引用和比较以确定元素是否相等(或使用内置方法,如Arrays.equals())。

    一个示例解决方案是:

    public static boolean testerFunction(int... elems){
        for(int[] candidate : Obsticle){
            // Filter out null and mismatching length arrays.
            if(candidate == null || candidate.length != elems.length){
                continue;
            }
    
            // Check equivilence using Arrays.equals()
            if(Arrays.equals(candidate, elems)){
                return true;
            }
        }
    
        // No arrays matched, return false
        return false;
    }
    

    【讨论】:

      【解决方案3】:

      只是为了介绍 Java 8 解决方案:

      public boolean testerFunction(int[][] arr2d, int... ints) {
          return Arrays.stream(arr2d).anyMatch(arr -> Arrays.equals(arr, ints));
      }
      

      请注意,第二个参数是一个可变参数数组,显然可以将其更改为像 OP 示例中那样简单地采用两个整数。

      该示例使用 Java 8 Streams,您可以找到 great tutorial on streams here

      【讨论】:

        猜你喜欢
        • 2015-04-16
        • 2012-05-12
        • 1970-01-01
        • 2018-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-22
        • 1970-01-01
        相关资源
        最近更新 更多