当你在arraylist上调用remove(object o)时,它如何比较对象?

Tho*_*nes 29 java compare arraylist

当你在java中的arraylist上调用remove(object o)时,如何比较对象以找到要删除的正确对象?它是否使用指针?还是使用Comparable接口比较对象?

Eri*_*ric 17

ArrayList remove()依赖于方法的对象实现Equal.如果没有执行任何实现,则通过Object实现删除对象,Equals其实际上是指针比较.

从文件ArrayList-

更正式地,删除具有最低索引i的元素,使得(o==null ? get(i)==null : o.equals(get(i)))(如果存在这样的元素)

对象equal方法文档 -

类Object的equals方法实现了对象上最具辨别力的等价关系; 即,对于任何非空的参考值xy,当且仅当该方法返回true x,并y指代相同的对象(x == y具有值true).


pol*_*nts 8

您应该始终查阅API以获取此类信息.

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

也许你对此感到困惑,例如TreeSet:

java.util.TreeSet:请注意,如果要正确实现接口,则由集合维护的排序(无论是否提供显式比较器)必须与equals一致Set.(有关与equals一致的精确定义,请参阅Comparable或Comparator.)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此两个被视为相等的元素从该集合的角度来看,通过这种方法是相等的.

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


一个说明性的例子

以下代码段说明了使用equals(例如ArrayList)和使用compare/compareTo(例如a TreeSet)的集合的集合之间的行为差​​异.

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
    }
}
Run Code Online (Sandbox Code Playgroud)