Your SlideShare is downloading. ×
0
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Java bestpractice common methods
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Java bestpractice common methods

946

Published on

Java bestpractice common methods

Java bestpractice common methods

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
946
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Best Practices withJava Common Object Methods Ulrik Hørlyk Hjort BestPractice Consulting & Advising 2010 Kaiserslautern 06.07.2010
  • 2. Java Common Object Methods►Intro►equals method►hashCode method►toString method►Cloneable interface and clone method►Comparable interface and compareTo method
  • 3. Objects And Nonfinal methods► Java objects are concrete classes primarily designed for extension►The nonfinal methods: ■ equals, hashCode, toString, clone, finalize all have explicit general contracts because they are designed to be overridden►Comparable.compareTo is not an Object method but has a similar character
  • 4. Common Object methods The equals method
  • 5. The equals methods contract►The equals method for the class Object implements the most discriminating possible equivalence relations on objects► The contract says: ■ For any reference values x and y, the equal method returns true if and only if x and y refer to the same object: x==y has the value true public boolean equals(Object obj) { return (this == obj); }
  • 6. equals method►When to override Object.equals ? ■ When a class has a notion of logical equality that differs from mere object identity ■ A superclass has not already overriden the equals method ■ Generally the case for value classes such as Integer and Date Integer a = new Integer(1); Integer b = new Integer(1); a.equals(b) evaluates to true a == b evaluates to false
  • 7. equals method►Value classes that do not require equals to be overriden are instance controlled classes like: ■ Singleton classes ■ Noninstantiable classes
  • 8. equals method►An overriden equals method must adhere to the general contract and implement the following equivalence relation for any non-null reference: ■ Reflexivity: x.equals(x) is true ■ Symmetry: x.equals(y) is true => y.equals(x) is true ■ Transitivity: x.equals(y) is true and y.equals(z) is true => x.equals(z) is true ■ Consistency: Multiple invocations of x.equals(y) consistently returns true or false ■ x.equals(null) always returns false
  • 9. equals method: Reflexivity►An object must be equal to itself►Hard to violate unintentionally
  • 10. equals method: Symmetry►Two objects must agree on whether they are equal►Very easy to violate unintentionally►Considerthe following class and try to spot how the symmetry is violated:
  • 11. equals symmetry violationpublic final class CaseInsensitiveString { private final String s; public CaseInsensitiveString(String s) { if (s == null) throw new NullPointerException(); this.s = s; } @Override public boolean equals(Object o) { if (o instanceof CaseInsensitiveString) return s.equalsIgnoreCase( ((CaseInsensitiveString) o).s); if (o instanceof String) return s.equalsIgnoreCase((String) o); return false; }}
  • 12. equals symmetry violation►The symmetry is violated by the one way interoperability: if (o instanceof String) return s.equalsIgnoreCase((String) o);►Consider the following: CaseInsensitiveString cis = new CaseInsensitiveString("Java"); String s = "java";
  • 13. equals symmetry violation►cis.equals(s) returns true as expected since the equals method in CaseInsensitiveString knows about ordinary strings►s.equals(cis) returns false since the equals method in String is oblivious to case insensitive strings►Symmetry violation!►To fix the problem remove the attempt to interoperate with String from the equals method:
  • 14. equals symmetry violation solvedpublic final class CaseInsensitiveString { private final String s; public CaseInsensitiveString(String s) { if (s == null) throw new NullPointerException(); this.s = s; }@Override public boolean equals(Object o) { return o instanceof CaseInsensitiveString && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);}}
  • 15. Execise 1►Suppose you put a case insensitive string into a collection with the symmetry violation equals method above:List<CaseInsensitiveString> list = new ArrayList<CaseInsensitiveString>();list.add(cis);►What does list.contains(s) returns?
  • 16. Execise 1 Answer►The answer is undefined. It can returns true, false or throw a runtime exception. It depends on the current Java implementation►Once you have violated the equals contract, you simply do not know how other objects wil behave when confronted with your object
  • 17. equals symmetry and inheritance►Another way the symmetry often is violated is when adding an aspect by extending an instantiable class►Consider: public class Point { private final int x, y; public Point(int x, int y) { this.x = x; this.y = y; } @Override public boolean equals(Object o) { if (!(o instanceof Point)) return false; Point p = (Point)o; return p.x == x && p.y == y; } }
  • 18. equals symmetry and inheritance►Now the class is extened with the notion of color to a point: public class ColorPoint extends Point { private final Color color; public ColorPoint(int x, int y, Color color) { super(x, y); this.color = color; } }
  • 19. equals symmetry and inheritance►The ColorPoint class equals method is inherited from Point and the color information is ignored►Not a contract violation but not acceptable, we need an equals method for color as well►An obvious solution seems to be: @Override public boolean equals(Object o) { if (!(o instanceof ColorPoint)) return false; return super.equals(o) && ((ColorPoint) o).color == color; }
  • 20. equals symmetry and inheritance►Do the symmetry hold?►No! Consider: Point p = new Point(1, 2); ColorPoint cp = new ColorPoint(1, 2, Color.BLUE);►p.equals(cp) returns true and cp.equals(p) returns false►To avoid violating the symmetry we could ignore color in mixed comparisons:
  • 21. equals symmetry and inheritance @Override public boolean equals(Object o) { if (!(o instanceof Point)) return false; if (!(o instanceof ColorPoint)) return o.equals(this); return super.equals(o) && ((ColorPoint)o).color == color; }►This approach provide symmetry►But what about transitivity?
  • 22. equals method transitivity►We recall: ■ Transitivity: x.equals(y) is true and y.equals(z) is true => x.equals(z) is true►And look at: ColorPoint p1 = new ColorPoint(1, 2, Color.BLUE); Point p2 = new Point(1, 2); ColorPoint p3 = new ColorPoint(1, 2, Color.RED);
  • 23. equals method transitivity►p1.equals(p2) and p2.equals(p3) returns true►p1.equals(p3) returns false►The transitivity is violated►As we see there is a fundamental problem of equivalence relations in OO languages►Itis not posible to extend an instantiable class and add a value component while preserving the equals contract!
  • 24. equals method transitivity►The solution: Favor composition over inheritance public class ColorPoint { private final Point point; private final Color color; public ColorPoint(int x, int y, Color color) { if (color == null) throw new NullPointerException(); point = new Point(x, y); this.color = color; } @Override public boolean equals(Object o) { if (!(o instanceof ColorPoint)) return false; ColorPoint cp = (ColorPoint) o; return cp.point.equals(point) && cp.color.equals(color); } }
  • 25. Be Careful!►Some classes in the Java platform libraries do extend an instantiable classes and add value components – and violate the symmetry!►Example: java.sql.Timestamp extends java.util.Date and adds a nanoseconds field►Do not mix the Timestamp and Date objects or use them in the same collection►Generally always be careful mixing different objects or use them in same collections
  • 26. Note►If you need to add a value component to a subclass in a safe way add it to an abstract class►As long as it is impossible to create a superclass instance directly the equal contract cannot be violated
  • 27. equals method Consistency►Recall:Multiple invocations of x.equals(y) consistently returns true or false►If two objects are equal the remain equal for all time unless one or both are modified►Mutable objects can be equal to different objects at different times – immutable cannot►For immutable objects make sure that the equals method enforces the restriction that equal objects remain equal and unequal objects remain unequal for all time
  • 28. equals method Consistency►Immutable class or not: Do not write an equals method that depends on unreliable resources►Example: The java.net.URL equals method relies on comparison of the IP addresses of the host associated with the URLs►Translating a host mane to an IP address can require network access, and it is not guaranteed to yield the same result over time►Thiscan cause (and has caused) the URL equals method to violate the equals contract
  • 29. Object not equal to null►The equals method always has to return false on x.equals(null)►The equals method may NOT throw a NullPointerException► Often the guard against this is done with an explicit null test: @Override public boolean equals(Object o) { if (o == null) return false }
  • 30. Object not equal to null►The explicit null test is not necessary►To make sure that the argument have the approipriate type for the equality test, the equals method must invorke the instanceof operator to check for the correct type►The instanceof operator is specified to return false if the first operand is null regardless of the second arument type
  • 31. Object not equal to null►The null object check is therefore done as a part of the object type check and cast: @Override public boolean equals(Object o) { if (!(o instanceof MyType)) return false; MyType mt = (MyType) o; }
  • 32. equals Summary►Overriding equals is not an easy task and there are many ways to get into problems. So when can overriding be avoided? ■ When each instance of the class is inherently unique ■ When the class do not need an logical equality test ■ When a super class already has done the overriding in an appropriate way for our class ■ When the class is private or package private and the equal method never will be invorked
  • 33. Execise 2►Are all 4 situations below safe ? ■ When each instance of the class is inherently unique ■ When the class do not need an logical equality test ■ When a super class already has done the overriding in an appropriate way for our class ■ When the class is private or package private and the equal method never will be invorked
  • 34. Execise 2 Answer►Not the last one. It is best practice to override the equals method in private and package private classes even you are certian it is never used.►In case the equals method is accidentally invorked: @Override public boolean equals(Object o) { throw new AssertionError(); }
  • 35. How to writing a good equals method 1►Use the == operator to check if the argument is a reference to the object►If so, return true.►Thisis a performance optimization to avoid potentially expensive comparisons
  • 36. How to writing a good equals method 2►Use the instanceof operator to check if the argument has the correct type►if not, return false►Typically, the correct type is the class containing the equals method►Occasionally, it is a interface implemented by the class (Like collection interfaces as Set, List, Map)
  • 37. How to writing a good equals method 3►Cast the argument to the correct type►Beacuse the instanceof test succeed this is guaranteed to succeed
  • 38. How to writing a good equals method 4►For each significant field in the class, check if the field of the argument matches the corresponding field of the object►If all test succeed, return true otherwise return false►Forfields whoose type is not float or double use the == operator for comparions►For float use Float.compare►For double use Double.compare
  • 39. How to writing a good equals method 4 (Cont.)►For array elements apply these guidelines to each significant element. If all elements are significant use one of the Array.equals methods►Forobject reference fields invorke the equals methods recursively►Some object references may legitimately contain null►To avoid a nullPointerException compare such fields as:
  • 40. How to writing a good equals method 4 (Cont.)(f eld == null ? o.f eld == null : f eld.equals(o.f eld)) i i i i►Some field comparisons are complex and expensive (e.g as CaseInsensitiveString). Consider to store such fields on a cannoncical form.►Forbest performance compare fields first that are more likely to differ
  • 41. How to writing a good equals method 5►When you are finished writing the equals method write unit tests to verify the three “tricky” properties holds: ■ Symmetry ■ Transitivity ■ Consistency
  • 42. How to writing a good equals method 6►Always override the hashCode method when override the equals method – We will look at that in the next section
  • 43. Execise 3►Explain how the following equals method will work: public boolean equals(MyClass o) { }
  • 44. Execise 3 Answer►The method does not override the equals method but overloads it! A common mistake often leading to hours of debugging!►Never substitute another type for Objects in the equals declaration►Can we avoid this mistake ?►Yes!Consistent use of the @override annotation will prevent such mistakes by giving a compiler error
  • 45. Execise 3 Answer►The correct overloaded equals method will therefore be:@Override public boolean equals(Object o) {}
  • 46. Execise 4►In the next section we will look at the hashCode method for the class below. But first we need to write the equals method: public class HashTest { private int num; private String data; public HashTest(int num, String data) { this.num = num;this.data = data;} }
  • 47. Execise 4 Answerpublic class HashTest { private int num; private String data; public HashTest(int num, String data) { this.num = num;this.data = data;} @override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof HashTest)) return false; HashTest ht = (HashTest)o; return num == ht.num && (data == ht.data || (data != null && data.equals(ht.data))); }}
  • 48. Common Object methodsThe hashCode method
  • 49. The hashCode method►Returnsthe hash code value for the object on which the method is invorked►The returned hash code is an integer value used by hashing based collections such as Hashtable, HashMap and HashSet►Must be overriden in every class where equals is overriden
  • 50. The hashCode contract►From the JavaSE6 Object specification ■ Whenever it is invoked on the same object more than once during an exection of an application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execu- tion of an application to another execution of the same application.
  • 51. The hashCode contract (Cont.)■ If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.■ It is not required that if two objects are unequal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.■
  • 52. The hashCode method►Two distinct instances which are logically equal according to the classs equals method are two objects with nothing in common according to the Objects hashCode method►The Objects hashCode method typically returns an integer value based on the objects internal address►Lookat the following class without a hashCode method:
  • 53. The hashCode methodpublic class HashTest { private int num; private String data; public HashTest(int num, String data) { this.num = num;this.data = data;} @override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof HashTest)) return false; HashTest ht = (HashTest)o; return num == ht.num && (data == ht.data || (data != null && data.equals(ht.data))); }}
  • 54. The hashCode method►Use the class with a HashMap:Map<HashTest, String> m = new HashMap<HashTest, String>();m.put(new HashTest(1,"foo"), "bar");►What do m.get(new HashTest(1,"foo")) returns?►Not “bar” as expected but null►Due to the missing hashCode method the to equal instances have unequal hash codes►The calling sequence is the hashCode method and then - on succes - the equals method
  • 55. Writing the hashCode method►How do we write a proper and legal hashCode method?►What about ? @override public int hashCode() { return 42; }►Itis legal according to the contract but useless since every object hases to the same bucket
  • 56. Writing a good hashCode method►Recall the third provision of the contract: ■ “... the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.”►The ideal hashCode method should distrubute any resonable collection of unequal instances uniformly across all possible hash values►Itis not possible to achieve that but Sun provide a recipe for a fair approximation:
  • 57. The hashCode method recipe►Store an arbitrary constant nonzero value in an int variable called hash. Ex. hash = 7►Foreach field f in the object which is taken into account by the equals method do: ■ Compute an int hash code c for the field according to the type: ► boolean, compute (f ? 1:0) ► byte, char, short or int, compute (int) f ► long, compute (int) (f^(f >>> 32)) ► float, compute Float.floatToIntBits(f)
  • 58. The hashCode method recipe (Cont.) ► double, compute Double.doubleToLongBits(f) and then follow the step above for hashing a long result ► If f is an object reference and this class equals method compare f by recursiverly invorking of the equals method then recursiverly invorke the hashCode method on f . If f is null return 0 ► If f is an array, treat each significant element as a seperate field and apply the relevant field rules as described above. If all fields of the array are significant use one of the Array.hashCode methods (Java 1.5 and up)■ Update the hash variable with c as follows: hash = 31 * hash +c;
  • 59. The hashCode method recipe (Cont.)►When the above recipe is done on all significant fields, return hash►When done writing the hashCode method verify (read: unit test!) that all equal instances have equal hash codes►Important:Do NOT include fields in the hash code compution that are not used in the equals comparisons! Question: Why not?►Because it violate the second provision of the contract
  • 60. Execise 5►Why is it important that the initial value of hash is not zero?►What is the idea with the multipication in: hash = 31 * hash +c; ?
  • 61. Execise 5►An nonzero value is choosen so the overall hash value will not be zero in case of the value hc computed is zero►The multiplication makes the result depend on the order of the fields which gives a better hash code in case of multiple similar fields. Consider a hashCode method for String, which will have identical hash codes for all anagram if the multipication was omitted
  • 62. Execise 6►Write the hashCode method for the class (hint: look at the equals method in execise 4) : public class HashTest { private int num; private String data; }
  • 63. Execise 6 Answerpublic class HashTest { private int num; private String data; @override public int hashCode() { int hash = 7; hash = 31 * hash + num; hash = 31 * hash + (null == data ? 0 : data.hashCode()); return hash; }}
  • 64. The hashCode method►Ifa class is immutable consider cashing the hash code with a lazy initialialization, rather than recalculate it each time the hashCode method is invorked: public class HashTest { private int num; private String data; private volatile int hashCode; @override public int hashCode() { int hash = hashCode; if (hash == 0) { hash = 31 * hash + num; hash = 31 * hash + (null == data ? 0 : data.hashCode()); hashCode = hash; } return hash; } }
  • 65. The hashCode method►Do not exclude significant parts of an object from a hash code computation to improve performance ■ Question: Why not?►Do not specify the exact value returned by the hashCode method ■ Question: Why not?
  • 66. Common Object methodsThe compareTo method
  • 67. The compareTo method►The Comparable interface is a mixedin interface for objects to advertise they permit cloning►The compareTo method is not declared in Object but is a sole method in the java.lang.Comparable interface►Similar in nature to equals and hashCode methods►A class who implements Comparable indicate that the instance have a natural ordering
  • 68. The compareTo method►Implementing Comparable allows: ■ calling Collections.sort and Collections.binarySearch ■ calling Arrays.sort and Arrays.binarySearch ■ using objects as keys in TreeMap ■ using objects as elements in TreeSet
  • 69. The compareTo method►The following example relies on the fact that Integer implements Comparable: public IntegerList { public static void main(String[] args) { Integer[] iList = {4,2,2,42,16}; Set<Integer> i = new TreeSet<Integer>(); Collections.addAll(s, iList); System.out.println(i); } } [2, 4, 16, 42]
  • 70. The compareTo method►By implementing Comparable the class is allowed to interoperate with all of the many generic algorithms and collections implementations depending on this interface►Tremendous amount of power for small amount of effort!
  • 71. The compareTo method►The general contract for compareTo is similar to the contract for the equals method: ■ “Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. Throws ClassCastException if the specified object’s type prevents it from being compared to this object.”
  • 72. The compareTo method►Toallow objects to be fully sorted the compareTo method needs to satisfy the following conditions: ■ Anticommutation: x.compareTo(y) is the opposite sign of y.compareTo(x) ■ Exception Symmetry: x.compareTo(y) throws the excatly same exception as y.compareTo(x)
  • 73. The compareTo method■ Transitivity: ► if x.compareTo(y)>0 and y.compareTo(z)>0, then x.compareTo(z)>0 ► if x.compareTo(y)<0 and y.compareTo(z)<0, then x.compareTo(z)<0 ► if x.compareTo(y)==0 then x.compareTo(z) and y.compareTo(z) has the same sign
  • 74. The compareTo method■ equals consistency: ► Highly recommended, but not required ► x.compareTo(y)==0, if and only if x.equals(y) ► consistency with equals is required for ensuring sorted collections - such as TreeSet - are well-behaved.
  • 75. The compareTo method► Withina class any reasonable ordering relation will satisfy the contract equals the compareTo method is not required to► Unlike work across classes and is permitted to throw an ClassCastException if to objects of different classes are compared► As with hashCode a violation of the contract can break other classes depending on comparison like sorted collections, TreeSet, TreeMap and the utility classes Collections and Arrays containing search and sort algoritms
  • 76. The compareTo method►A consequence of the three provisions: Anticommutation, Symmetry and Transitivity is – like equals – that there is no simple way to extend an instantiable class with a new aspect while preserving the contract►If a new significant aspect need to be added to the class use composition instead of inheritance (as with equals)
  • 77. The compareTo method►Be aware if the compareTo method imposes an order inconsistent with equals►Sortedcollections containing elements of the class may not obey the general contract of the appropriate collection interfaces – Collection, Set, Map
  • 78. Example: Inconsistent equals and compareTo methods►Inthe following the set wil contain two elements because the equals method is used for comparison: public class Inconsistent { public static void main(String [] args) throws IOException { Set<BigDecimal> Hs = new HashSet<BigDecimal>(); Hs.add(new BigDecimal("42.0")); Hs.add(new BigDecimal("42.00")); Iterator<BigDecimal> It = Hs.iterator(); while (It.hasNext()) { System.out.println(": "+It.next()); } } }
  • 79. Example: Inconsistent equals and compareTo methods►Inthe following the set wil contain one element because the compareTo method is used: public class Inconsistent { public static void main(String [] args) throws IOException { Set<BigDecimal> Ts = new TreeSet<BigDecimal>(); Ts.add(new BigDecimal("42.0")); Ts.add(new BigDecimal("42.00")); Iterator<BigDecimal> It = Ts.iterator(); while (It.hasNext()) { System.out.println(": "+It.next()); } } }
  • 80. Writing the compareTo method►Writing the compareTo method is almost similar to writing the equals method►Type check for casting is not needed. If the argument is not of the appropriate type thow the ClassCastException►Ifthe argument is null the compareTo method shall throw a NullPointerException (The behavior as if the argument is type casted and an attempt to access the members is done)
  • 81. Writing the compareTo method►Remember: The field comparisons are order comparisons rather than equality comparisons as for equals►
  • 82. Writing the compareTo method►Various types of fields are compared as follows: ■ numeric primitive : Use < and >. ► Forfloat and double primitives use Float.compare(float, float) and Double.compare(double, double). ■ boolean primitive : Use tests of the form (x && !y) ■ Object references: Use compareTo invorked recursively ■ Arrays: Apply the above guidelines to each element
  • 83. Writing the compareTo method►Ifa field does not implement Comparable or a non standard ordering need to be used write or use an explicit Comparator.►If the class has multiple significant fields the comparison order will be critical. Start with the most significant field and work down►Ifa comparison result is different from zero then stop the comparison and return the result►Ifall fields are equals, the objects are equal, return zero
  • 84. Execise 7►Write the compareTo method for the following class: public class CompareTo_Class { private String name; private int number; private boolean isOk; public int compareTo( CompareTo_Class cc ) { } }
  • 85. Execise 7 Answerpublic class CompareTo_Class implements Comparable<CompareTo_Class> { private String name; private int number; private boolean isOk; public int compareTo( CompareTo_Class cc ) { if (this.number < cc.number) return -1; if (this.number > cc.number) return 1; if (!this.isOk && cc.isOk) return -1; if (this.isOk && !cc.isOk) return 1; int comparison = this.name.compareTo(cc.name); if ( comparison != 0 ) return comparison; return 0; }}
  • 86. Execise 7 Answer►Did you remember to implement the Comparable interface?►IMPORTANT: Implementing the Comparable interface is telling the Java type-checker and the runtime system, that you have provided a compareTo() method. Without that information you will not be allowed to use your objects where a Comparable interface is expected even though they do have the implemented the compareTo method.
  • 87. Execise 7 Answerpublic class CompareTo_Class implements Comparable<CompareTo_Class> { public int compareTo( CompareTo_Class cc ) { if ( this == cc ) return 0; if (this.number < cc.number) return -1; if (this.number > cc.number) return 1; if (!this.isOk && cc.isOk) return -1; if (this.isOk && !cc.isOk) return 1; int comparison = this.name.compareTo(cc.name); if ( comparison != 0 ) return comparison; assert this.equals(cc) : "compareTo inconsistent with equals."; return 0; }}
  • 88. Execise 7 Answer►Doing the test if ( this == cc ) return 0; before doing any comparisions, to verify that the object is not compared to it self, is a worthwhile optimization►Ifthe compareTo method has to be equals consistent add assert this.equals(cc) : "compareTo inconsistent with equals."; before the last return statement
  • 89. Execise 7 Answer►Since the contract does not specify the magnitude of the return value from compareTo it is possible to improve it using that fact: public class CompareTo_Class implements Comparable<CompareTo_Class> { public int compareTo( CompareTo_Class cc ) { int numberDiff = this.number – cc.number; if (numberDiff !=0) return numberDiff; ... return 0; } }
  • 90. Execise 7 Answer►But use this trick with caution! Never use it if: ■ The field in question can be negative ■ The difference between the lowest and highest possible field values is less than or equal to Integer.MAX_VALUE (2^31-1)
  • 91. Common Object methods The clone method
  • 92. The clone method► The Cloneable interface was intended as a mixedin interface for objects to advertise they permit cloning► Problems: ■ The Cloneable interface lacks a clone method! ■ Objects clone method is protected!► Cloneabledetermines the behavior of Objects protected clone method, returns field by field copy of the object► Ifa class implements Cloneable, Objects clone method returns a field by field copy of the object – otherwise it throws CloneNotSupportedException
  • 93. The clone method►Note: The use of an interface to modify the behavior of a protected super class method as Cloneable do is NOT good style! Never do it! Interfaces shall only be used to say something about what a class can do for its clients
  • 94. The clone methodSummary: It is very hard to implement Cloneable rightand it is not the effort worth to try – so never use theclone method!
  • 95. Common Object methods The toString method
  • 96. The toString method►Provides a simple convenient mechanism for: ■ Debugging classes during development ■ Logging ■ Passing error messages to exception constructors and assertions►More formally toString can be used to translating an object into a well-defined textual form (toString) and back again (valueOf)
  • 97. The toString method Contract►The general toString contract says: ■ “Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.”
  • 98. The toString method►The toString method is not so important as the previous methods►The toString method should return all of the interesting information contained in the object►Ifthe object is large or contains states that are not conducive to string representation the toString method should return a summary
  • 99. The toString method►Speciallyfor value classes consider to specify the format of the return value ■ Example: Look at the specification for the toString(double d) in the Double class►Ifthe format is specified consider to provide a matching String constructor or a static factory – like the valueOf method – to translate back to the Object from its string representation ■ Example: Look at the valueOf(String s) method in the Double class
  • 100. The End►

×