【发布时间】:2011-02-23 02:09:20
【问题描述】:
当您在 java 中的 arraylist 上调用 remove(object o) 时,它如何比较对象以找到要删除的正确对象?它使用指针吗?还是使用 Comparable 接口比较对象?
【问题讨论】:
当您在 java 中的 arraylist 上调用 remove(object o) 时,它如何比较对象以找到要删除的正确对象?它使用指针吗?还是使用 Comparable 接口比较对象?
【问题讨论】:
ArrayList remove() 依赖于 Equal 方法的对象实现。如果没有实现,那么对象会被Object 的Equals 实现移除,这确实是指针比较。
来自ArrayList 上的文档-
更正式地说,删除具有最低索引 i 的元素,例如
(o==null ? get(i)==null : o.equals(get(i)))(如果存在这样的元素)
对象equal方法文档-
Object 类的 equals 方法实现了对象上最有区别的可能等价关系;也就是说,对于任何非空引用值
x和y,当且仅当x和y引用同一个对象(x == y具有值true)时,此方法才返回 true。
【讨论】:
您应该始终查阅 API 以获取此类信息。
ArrayList.remove(Object o):从该列表中删除第一次出现的指定元素(如果存在)。如果列表不包含该元素,则它不变。更正式地说,删除具有最低索引的元素i使得(o==null ? get(i)==null : o.equals(get(i)))(如果存在这样的元素)。
也许您将其与例如TreeSet:
java.util.TreeSet:注意,如果要正确实现Set接口,集合维护的顺序(无论是否提供显式比较器)必须与equals一致。 (请参阅 Comparable 或 Comparator 以获得与等于一致的精确定义。)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用其compareTo执行所有元素比较(或compare)方法,因此从集合的角度来看,此方法认为相等的两个元素是相等的。
(不幸的是,例如TreeSet.remove 方法本身并没有任何明确提醒上述警告,但至少它被放在类文档顶部的显着位置)
以下 sn-p 说明了使用 equals(例如 ArrayList)的集合和使用 compare/compareTo(例如 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
}
}
【讨论】:
docs 回答您的问题:
删除单个实例 从此指定元素 集合,如果存在(可选 手术)。更正式地说,删除一个 元素
e这样(o==null ? e==null : o.equals(e)),如果集合 包含一个或多个此类元素。
【讨论】:
它使用equals()
来自docs:
从该列表中删除第一次出现的指定元素(如果存在)。如果列表不包含该元素,则它不变。更正式地说,删除具有最低索引 i 的元素,使得 (o==null ? get(i)==null : o.equals(get(i))) (如果存在这样的元素)。如果此列表包含指定元素(或等效地,如果此列表因调用而更改),则返回 true。
【讨论】: