1 / 21

clone()

clone(). Defined in Object Creates an identical copy Copies pointers to fields (does not copy fields of fields) Makes a shallow copy if the object’s class doesn’t implement Cloneable , a CloneNotSupportedException is thrown x.clone () != x;

balice
Download Presentation

clone()

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. clone() • Defined in Object • Creates an identical copy • Copies pointers to fields (does not copy fields of fields) • Makes a shallow copy • if the object’s class doesn’t implement Cloneable, a CloneNotSupportedException is thrown • x.clone() != x; • Modification to X no longer affect X.clone( ) • x.clone.getClass() == x.getClass(); • Usually,x.equals(x.clone()) == true; • However, this is not a requirement

  2. Why Override clone()? • First, Object’s clone is a protected method • Its visibility can be increased: • Sometimes a deeper copy of a field is required publicclass X implements Cloneable {public Object clone () throws CloneNotSupportedException { return super.clone(); } } publicclass X implements Cloneable { private A a;public Object clone () throws CloneNotSupportedException { X x = (X)super.clone(); if(a != null) x.a = (A)a.clone(); return x; } }

  3. Pitfalls in Overriding clone() • Implementing clone() using a constructor publicclass X implements Cloneable {public Object clone () throws CloneNotSupportedException { return new X(); } } publicclass Y extends X {//use clone from X } Clone returns wrong type! publicclass Y extends X {public Object clone () throws CloneNotSupportedException { Y y = (Y)super.clone(); … } } Exception!

  4. Pitfalls in clone() - Cont • Using Constructors to copy subobjects • if field a refersto an object of a subclass of A, the cloned object will be different from the original publicclass X implements Cloneable {private A a; public Object clone () throws CloneNotSupportedException { X x = (X)super.clone(); if(a != null) x.a = new A(); return x; } }

  5. equals(), hashCode() • Are defined in Object • equals() • Used for state equality testing • as opposed to operator == used for reference equality • Used for test containment of object in collection • Used for storing an object in hash-based collection • hashCode() • Returns an int value representing the object • Used for storing an object in hash-based collections

  6. hashCode() in insertion publicclass SimpleHashSet { private List<Integer> hashCodes = new ArrayList<Integer>(); private List<List<Object>> lists = new ArrayList<ArrayList<Object>>();   publicvoid add(Object o) { List<Object> lst = null; for(int i=0; lst==null && i<hashCodes.size(); ++i) if(hashCodes.get(i) == o.hashCode()) lst = objects.get(i); if(lst == null) { hashCodes.add(o.hashCode()); lists.add(lst = new ArrayList<Object>()); }   lst.add(o); }   }

  7. equals, hashCode in containment test publicclass SimpleHashSet { … public boolean exists(Object o) { List<Object> lst = null; for(int i=0; lst==null && i<hashCodes.size(); ++i) if(hashCodes.get(i) == o.hashCode()) lst = objects.get(i); if(lst == null) returnfalse; for(Object elem : lst) if(elem.equals(o)) returntrue; returnfalse; }   }

  8. Overriding equals() • Default implementation of equals() • is based on the == operator • Two objects are equal if and only if they are the same object • Sometimes a programmer specific notion of identity is required: Date d1 = new Date(2007, 7, 7); Date d2 = new Date(2007, 7, 7); d1 != d2; d1.equals(d2) == true;

  9. equals() Contract • The equals() method implements an equivalence relation: • It is reflexive • a.equals(a) is true • It is symmetric • a.equals(b)⇔b.equals(a) • It is transitive • a.equals(b) and b.equals(c)⇒a.equals(c) • It is consistent • repeated calls to the method must yield the same result unless the arguments are modified in-between • No object equals null • a.equals(null) = false

  10. equals() Contract • The contract is defined in Java documentation: • http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#equals(java.lang.Object) • The contract is not enforced by the compiler or the runtime system!

  11. A Naïve Example class Point{ private finalint x; private finalint y; publicboolean equals(Object o){ if (!(o instanceof Point)) returnfalse; return ((Point)o).x == x && ((Point)o).y == y; } } Meets all contract’s demands (as long as inheritance is not involved…)

  12. Extending the Point Class classColorPointextends Point{ private final Color color; publicboolean equals(Object o){ if (!(o instanceofColorPoint)) returno.equals(this); returnsuper.equals(o) && ((ColorPoint)o).color == color; } } ColorPoint p1 = new ColorPoint(1, 2, Color.RED); Point p2 = new Point(1, 2); p1.equals(p2); // ??? P2.equals(p1); // ???

  13. Another try classColorPointextends Point{ final Color color; publicboolean equals(Object o){ if (!(o instanceof Point)) returnfalse; if (!(o instanceofColorPoint)) returno.equals(this); returnsuper.equals(o) && ((ColorPoint)o).color == color; } } ColorPoint p1 = new ColorPoint(1, 2, RED); Point p2 = new Point(1, 2); ColorPoint p3 = new ColorPoint(1, 2, BLUE); p1.equals(p2); // ??? p2.equals(p3); // ??? p3.equals(p1); // ???

  14. A Safe Solution classColorPointextends Point{ final Color color; publicboolean equals(Object o){ if (o.getClass != ColorPoint.class) returnfalse; returnsuper.equals(o) && ((ColorPoint)o).color == color; } } • Meets all the contract’s requirements • May be too strict • An object is never equals to an instance of its super class • Even if the derived class doesn’t add fields

  15. Another Solution • The idea: two objects must agree on their equality class Point{ … protectedboolean eq(Object o) { if(!(o instanceof Point)) returnfalse; return ((Point)o).x == x && ((Point)o).y == y; } publicboolean equals(Object o){ return (this.eq(o) && o.eq(this)); } } class ColorPoint extends Point{ … publicboolean eq (Object o){ if (!(o instanceof ColorPoint)) return false; returnsuper.eq(o) && ((ColorPoint)o).color == color; } }

  16. hashcode() Contract • It is consistent • repeated calls to the method must yield the same int unless the arguments are modified in-between • Must generate equal values for equal objects We see that hashcode() is closely related to equals() • if you override equals, you must override hashCode

  17. hashcode / equals contract violation class Point{ finalprivateint x, y; publicboolean equals(Object o){ if (!(o instanceof Point)) returnfalse; return ((Point)o).x == x; } publicinthashCode() { return 19 * y; { } publicstaticvoid main(String[] args) { Set<Point> s = newHashSet<Point>(); Point p1 = new Point(1, 2); s.add(p1); Point p2 = new Point(1, 3); //p1.equals(p2) is true System.out.println(s.contains(p2)); // false }

  18. Comparable Interface • Why? • equals() can compare objects of different classes • equals() is boolean – can’t be used for sorting • A problem • we want compareTo to take a parameter of the same type as the receiver • requires a covariant parameter • The Solution • Using generics: publicinterface Comparable<T> { int compareTo(T o); }

  19. Implementing Comparable publicclass Person implements Comparable<Person> { public String name; public int age;   // Order by age then by name public int compareTo(Person p) { int diff = this.age - p.age; if(diff != 0) return diff;   // Use compareTo of String returnthis.name.compareTo(p.name); } }

  20. Using compareTo() publicstatic <T extends Comparable<T>> void sort(List<T> lst) { int top = lst.size(); for(int i = 0; i < top; ++i) { for(int j = 1; j < top; ++j) { T a = lst.get(j-1); T b = lst.get(j); if(a.compareTo(b) > 0) { lst.set(j-1 ,b); lst.set(j, a); } } } }

  21. Comparator Interface • Used for comparing objects of a class that does not implement Comparable publicInterface Comparator<T> { publicintcompare(T o1, T o2); }   publicclassUtils { publicstatic<T> boolean isOrdered(Comparator<T> comp, T... ts) { for(inti = 1; i < ts.length; ++i) if(comp.compare(ts[i], ts[i-1]) < 0) returnfalse; returntrue; } }

More Related