【问题标题】:pass "new Integer (any number)" as a parameter to the remove method of an ArrayList将“new Integer (any number)”作为参数传递给 ArrayList 的 remove 方法
【发布时间】:2020-12-08 03:54:58
【问题描述】:

当我像这样创建一个 ArrayList 时:

ArrayList<Integer> arr = new ArrayList
arr.add(1);
arr.add(3);
arr.add(34);
arr.add(13);

然后我尝试删除作为参数传递的元素new Integer(34)

arr.remove(new Integer(34));

那条线是如何工作的? 我在创建一个新的整数对象吗? 不应删除任何元素,因为在方法中创建的元素与在 ArrayList 中创建的元素存储在不同的内存位置。对吧?

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    当您调用new Integer(34) 时,肯定会创建一个新的 Integer 对象。但是 Integer 类已经覆盖了 equalshashCode 方法。

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    
    
    public int hashCode() {
        return Integer.hashCode(value);
    }
    

    在您的代码中,当您调用Arr.remove(new Integer(34)) 方法时,会从ArrayList 调用remove(Object o)

    public boolean remove(Object o) {
            if (o == null) {
                for (int index = 0; index < size; index++)
                    if (elementData[index] == null) {
                        fastRemove(index);
                        return true;
                    }
            } else {
                for (int index = 0; index < size; index++)
                    if (o.equals(elementData[index])) {
                        fastRemove(index);
                        return true;
                    }
            }
            return false;
        }
    

    从上面的代码可以看出,当o (Object)不为空时,它会调用equals来检查是否相等并从列表中删除对象。因此,您的对象被删除,即使它具有不同的内存位置。

    还有一点:

    考虑使用Integer.valueOf(34) 方法而不是new Integer(34)Integer.valueOf(34) 如果已经在其他地方的代码中创建了现有实例,则会为您提供现有实例。由于 Integer 是不可变的,因此不会产生任何问题。所以不需要每次都使用new关键字创建新对象。

    【讨论】:

    • 非常感谢,您的回答帮助了我的问题。感谢您提供代码,您的回答是最好的
    【解决方案2】:

    在内部,java.util.ArrayList 使用 .equals() 在尝试从列表中删除元素时进行比较。

    在您的情况下,它将删除值为 34 的元素,因为它是 int 的包装类型,它是 Object

    但是如果你使用原始类型,它会抛出IndexOutOfBoundException。 这是因为它将调用另一个接受原始类型的remove() 方法,并且此方法将删除索引 34 处的元素,该元素在上面的列表中不存在,只有 4 个元素。

    顺便说一句,以后你不应该对任何包装类使用构造函数方法,因为它自 Java 9 以来已被弃用,并将在 Java 16 中删除。你应该在创建包装对象时使用静态 .valueOf() 方法原始类型。

    【讨论】:

    • 非常感谢,您的回答帮助了我的问题。
    【解决方案3】:

    首先,您可以简单地转换为 Integer。其次,您应该更喜欢 Java 命名约定。第三,Arrays.asList 不那么尴尬。四、可以打印List。最后,(正如您所怀疑的)这里还有更多工作要做。使用 new Integer(int) 时,只有 byte 范围内的值才能保证被缓存(因此您应该避免这种情况,要么强制转换,要么使用 Integer.valueOf(int))。

    List<Integer> al = new ArrayList<>(Arrays.asList(1, 3, 34, 13));
    System.out.println(al);
    al.remove((Integer) 34);
    System.out.println(al);
    

    【讨论】:

    • 如果在上述问题中使用Arrays.asList(),在调用remove() 时会抛出UnsupportedOperationException,因为Arrays.asList() 返回的List 类是不可变的。
    • @MKTan 这就是我使用new ArrayList&lt;&gt;(Arrays.asList(1, 3, 34, 13)) 的原因 - 它按预期工作。
    • 糟糕。没看到那个。对不起。
    【解决方案4】:
    According to Arraylist implementation remove method is based on equals().
    
        For Integer equals is overridden as follow and based on int value but not on object reference
    

    整数等于

    public boolean equals(Object obj){
        if(obj instanceof Integer){
            return value==((Integer)obj).intValue();
        }
        return false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-13
      • 2015-06-07
      • 2014-12-27
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多