“contains”方法不适用于arraylist< int[]>,还有其他方法吗?

mnowg1ta  于 2021-06-27  发布在  Java
关注(0)|答案(5)|浏览(421)

我想添加一个 int[] 如果它还没有的话 int[] ,但由于某种原因,它不起作用。在本例中,arrlist是 ArrayList<int[]> 而arr是 int[] . 此代码位于for循环中,其中arr在循环中定义,因此arr中的值会更改。即使我打印了arrlist并且它有arr,代码也总是说arrlist不包含arr。有没有其他方法来检查arraylist是否包含 int[] ?

int n = scan.nextInt();
ArrayList<int[]> arrlist = new ArrayList<>();
int[][] coordinates = new int[n][2];
boolean[] isTrue = new boolean[n];
for (int j = 0; j < n; j++) {
    int[] arr = new int[2];
    arr[0] = coordinates[j][0];
    arr[1] = coordinates[j][1];
    if (arrlist.contains(arr)) {
        isTrue[j] = true;
    } else {
        arrlist.add(arr);
    }
}
bybem2ql

bybem2ql1#

由于数组不按元素进行比较,因此不能使用由实现的contains ArrayList . 你可以用 Arrays 让学生按照下面的步骤来做。创建一个采用 List 以及要检查的数组。记住数组不像集合,所以相等性取决于顺序。

public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    int n = scan.nextInt();
    List<int[]> arrlist = new ArrayList<>();
    int[][] coordinates = new int[n][2];
    boolean[] isTrue = new boolean[n];
    for(int j = 0; j < n; j++) {
        int[] arr = new int[2];
        arr[0] = coordinates[j][0];
        arr[1] = coordinates[j][1];
        if (contains(arrlist,arr)) {
            isTrue[j] = true;
        } else {
            arrlist.add(arr);
        }
    }
}
private static boolean contains(List<int[]> list, int[] b) {
    for (int[] a : list) {
        if (Arrays.equals(a,b)) {
            return true;
        }
    }
    return false;
}

你可以用一个 List<List<Integer>> 而不是 List<int[]> 因为大家都知道数组不能很好地处理列表。

izkcnapc

izkcnapc2#

试试这个:

if(arrlist.indexOf(arr)!=-1){
   isTrue[j] = true;
}

我认为在检查数组对象是否在列表中时,.contains方法可能有点奇怪。

px9o7tmv

px9o7tmv3#

在这种情况下,在创建 ArrayList 示例,可以重写其 contains 方法,该方法比较两个数组的内容,而不是比较两个数组对象的引用。此代码应适用于 Java 7 :

int[] a = {1, 2};
int[] b = {1, 2};

ArrayList<int[]> arrayList = new ArrayList<>() {
    @Override
    public boolean contains(Object that) {
        for (int i = 0; i < this.size(); i++)
            if (Arrays.equals(this.get(i), (int[]) that))
                return true;
        return false;
    }
};

arrayList.add(a);
System.out.println(arrayList.size());      // 1
System.out.println(arrayList.contains(a)); // true
System.out.println(arrayList.contains(b)); // true

你可以用 TreeSet 而不是 ArrayList 一个比较两个数组内容的比较器。那你可以用 TreeSet.contains 方法如下:

TreeSet<int[]> treeSet = new TreeSet<>(Arrays::compare);

treeSet.add(new int[]{1, 2});
treeSet.add(new int[]{1, 2});
treeSet.add(new int[]{1, 3});

System.out.println(treeSet.size());                    // 2
System.out.println(treeSet.contains(new int[]{1, 2})); // true
System.out.println(treeSet.contains(new int[]{1, 3})); // true
treeSet.stream().map(Arrays::toString).forEach(System.out::println);
// [1, 2]
// [1, 3]

另请参见:
•检查哈希集中是否存在数组<int[]>
•如何使两个数组具有不同的引用?

cu6pst1q

cu6pst1q4#

考虑以下代码:

int[] a = { 1, 2 };
   int[] b = { 1, 2 };
   System.our.println(a.equals(b));

你明白为什么输出是“假”吗?
这就是问题的原因:根据'equals'方法,内容相等的两个数组是不相等的,该方法在这里显式调用,在列表中隐式调用。
只要你想使用int[]数组,我就看不到一个简单的解决方法。不能定义equals方法。我认为,最好的方法是根本不使用数组来包含坐标。
定义一个类,其示例包含所需的两个整数:

class Point {
       int x, y;
       Point(int x, int y) {
          this.x = x;  this.y = y; 
       }
       boolean equals(Object o) {
           return o instanceof Point && 
                  x == ((Point)o).x && 
                  y == ((Point)o).y;
       }
   }

然后保存一个数组列表'“包含”现在将按预期工作。
(您还应该在类point中定义hashcode,但我跳过了它,它与答案并不直接相关)。

nnvyjq4y

nnvyjq4y5#

您需要比较 arr 与包含在 ArrayList arrlist .
最短解应为以下λ:
boolean contains = arrlist.stream().anyMatch( a -> arr[0] == a[0] && arr[1] == a[1] ); anyMatch 找到第一根火柴就停止

相关问题