Java clone()和equals()检查

时间:2014-09-12 10:03:14

标签: java object arraylist clone equals

对于以下类,我理解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();
  } 
}

4 个答案:

答案 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中建议使用)。

所以,你应该做两件事:

  1. 覆盖clone()
  2. 覆盖equals()(以及hashCode(),而你正好)