当你在数组列表上调用 remove(object o) 时,它是如何比较对象的?

2022-09-01 09:57:04

当你在java中的数组列表上调用demove(object o)时,它如何比较对象以找到要删除的正确对象?它使用指针吗?还是使用接口比较对象 可比性?


答案 1

ArrayList remove()依赖于该方法的对象实现。如果没有完成任何实现,则对象被 的实现删除,其实现确实是指针比较。EqualObjectEquals

从文档上ArrayList -

更正式地说,删除索引为 i 最低的元素,以便(如果存在这样的元素)(o==null ? get(i)==null : o.equals(get(i)))

对象方法文档 -equal

类 Object 的 equals 方法在对象上实现最有区别的可能等价关系;也就是说,对于任何非空引用值 和 ,此方法返回 true 当且仅当 和 引用同一对象 ( 具有值 )。xyxyx == ytrue


答案 2

有关此类信息,您应始终查阅 API。

ArrayList.remove(Object o):从此列表中删除指定元素的第一个匹配项(如果存在)。如果列表不包含该元素,则它保持不变。更正式地说,删除索引最低的元素,以便(如果存在这样的元素)。i(o==null ? get(i)==null : o.equals(get(i)))

也许你把它与例如:TreeSet

java.util.TreeSet:请注意,如果要正确实现接口,则由集合维护的排序(无论是否提供显式比较器)必须与 equals 一致。(有关与等数一致的精确定义,请参见“比较”或“比较器”。之所以如此,是因为接口是根据操作定义的,但是实例使用其(或)方法执行所有元素比较,因此从集合的角度来看,此方法认为相等的两个元素是相等的。SetSetequalsTreeSetcompareTocompare

(不幸的是,例如 TreeSet.remove 方法本身没有任何关于上述警告的明确提醒,但至少它位于类文档的顶部)


一个说明性的例子

以下代码段说明了使用的集合(如 )和使用的集合(如 )的行为差异。equalsArrayListcompare/compareToTreeSet

import java.util.*;

public class CollectionEqualsCompareTo {
    static void test(Collection<Object> col, Object o) {
        col.clear();
        col.add(o);
        System.out.printf("%b %b %b %b%n",
            col.contains(o),
            col.remove(o),
            col.contains(o),
            col.isEmpty()
        );
    }
    public static void main(String[] args) {
        Object broken1 = new Comparable<Object>() {
            // Contract violations!!! Only used for illustration!
            @Override public boolean equals(Object o)    { return true; }
            @Override public int compareTo(Object other) { return -1;   }
        };
        Object broken2 = new Comparable<Object>() {
            // Contract violations!!! Only used for illustration!
            @Override public boolean equals(Object o)    { return false; }
            @Override public int compareTo(Object other) { return 0;     }
        };
        test(new ArrayList<Object>(), broken1); // true true false true
        test(new TreeSet<Object>(),   broken1); // false false false false
        test(new ArrayList<Object>(), broken2); // false false false false
        test(new TreeSet<Object>(),   broken2); // true true false true
    }
}