对于以下类,我理解c1.equals(c3)
返回false,因为c1.clone()
创建指向同一对象的不同引用。但为什么carList1.equals(carList2)
返回true?为什么它与c1.equals(c3)
不同?非常感谢提前!
class Car implements Cloneable {
private String plate;
private double maxSpeed;
public Car(String lp, double max) {
license = lp;
maxSpeed = max;
}
public static void main(String[] args) throws Exception{
Car c1 = new Car("ABC123", 150.0);
Car c2 = new Car("ABC123", 150.0);
Car c3 = (Car) c1.clone();
ArrayList<Car> carList1 = new ArrayList<Car>();
carList1.add(c1);
carList1.add(c2);
ArrayList carList2 = (ArrayList) carList1.clone();
}
}
答案 0 :(得分:6)
clone
的{{1}}执行浅拷贝,即它不会克隆ArrayList
中包含的元素,它只是复制引用。这就是ArratList
返回true的原因,因为它不比较ArrayList对象的引用,它会比较列表中的元素。
public Object clone()
返回此ArrayList实例的浅表副本。 (要素 他们自己不被复制。)
public boolean equals(Object o)
将指定对象与此列表进行比较以获得相等性。返回 当且仅当指定的对象也是列表时才为true,两个列表都是如此 具有相同的大小,以及两者中所有相应的元素对 清单是平等的。 (如果(e1 == null,两个元素e1和e2相等)? e2 == null:e1.equals(e2))。)换句话说,定义了两个列表 如果它们包含相同顺序的相同元素,则相等。
另一方面,Car假设你没有覆盖它的equals
方法只是比较成员,使用Object :: equals的默认实现,它比较对象引用,因此克隆的Car是不等于原件。
答案 1 :(得分:0)
您的Car
课程未被覆盖equals()
。因此,它仅通过对象标识来评估相等性,默认行为 - 与==
运算符相同。
另一方面,ArrayList 已重写equals()
,它通过在列表中的所有元素上调用equals()
来完成它。如果列表&#39;元素都是相等的,那么列表是相等的。并且,正如另一个提到的答案,clone()
方法创建一个新列表,其中包含与原始文件相同的相同对象(而不是副本)。
答案 2 :(得分:0)
ArrayList没有equals()
方法。它扩展了AbstractList
,用于定义/实现equals()
。 clone()
仅复制引用,因此两个列表中的对象都是相同的。
来自oracle docs:equals()
执行此操作:
将指定对象与此列表进行比较以获得相等性。返回 当且仅当指定的对象也是列表时才为true,两个列表都是如此 具有相同的大小,以及两者中所有相应的元素对 清单是平等的。 (如果(e1 == null,两个元素e1和e2相等)? e2 == null:e1.equals(e2))。)换句话说,定义了两个列表 如果它们包含相同顺序的相同元素,则相等。这个 实现首先检查指定的对象是否为此列表。如果 所以,它返回true;如果没有,它会检查指定的对象是否为a 名单。如果不是,则返回false;如果是这样,它会遍历两个列表, 比较相应的元素对。如果任何比较返回 false,此方法返回false。如果任何迭代器耗尽 另一个元素返回false(如列表所示) 不等长);否则它在迭代时返回true 完整。
答案 3 :(得分:0)
这完全取决于equals(...)
的实施。 clone()
函数不会按原样复制所有内容,只要您不覆盖它(在Clonable JavaDoc中建议使用)。
所以,你应该做两件事:
clone()
equals()
(以及hashCode()
,而你正好)