Item 12: Consider implementing Comparable

1.  compareTo is the sole method in the Comparable interface. By implementing Comparable, a class indicates that its instances have a natural ordering.

 

2.  By implementing Comparable, you allow your class to interoperate with all of the many generic algorithms and collection implementations that depend on this interface. (Arrays.sort, Arrays.binarySearch, TreeSet, etc.)

 

3.  The general contract of the compareTo method:
    a)  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.

    b)  The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception if and only if y.compareTo(x) throws an exception.)

    c)  The implementor must also ensure that the relation is transitive: (x.compareTo(y) > 0 && y.compareTo(z) > 0) implies x.compareTo(z) > 0.
    d)  Finally, the implementor must ensure that x.compareTo(y) == 0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
    e)  It is strongly recommended, but not strictly required, that (x.compareTo(y) == 0) == (x.equals(y)). Violating this rule means this class has a natural ordering that is inconsistent with equals.


4.  compareTo should throw ClassCastException if two object references being compared refer to objects of different classes. As of release 1.6, no classes in the Java platform libraries that support interclass comparisons.

 

5.  A class that violates the compareTo contract can break other classes that depend on comparison. Classes that depend on comparison include the sorted collections TreeSet and TreeMap, and the utility classes Collections and Arrays, which contain searching and sorting algorithms.

 

6.  There is no way to extend an instantiable class with a new value component while preserving the compareTo contract, unless you are willing to forgo the benefits of object-oriented abstraction. If you want to add a value component to a class that implements Comparable, don’t extend it; write an unrelated class containing an instance of the first class. Then provide a “view” method that returns this instance.

 

7.  Consider the BigDecimal class, whose compareTo method is inconsistent with equals. If you create a HashSet instance and add new BigDecimal("1.0") and new BigDecimal("1.00"), the set will contain two elements because the two BigDecimal instances added to the set are unequal when compared using the equals method. If, however, you perform the same procedure using a TreeSet instead of a HashSet, the set will contain only one element because the two BigDecimal instances are equal when compared using the compareTo method.

 

8.  Compare object reference fields by invoking the compareTo method recursively. If a field does not implement Comparable, or you need to use a nonstandard ordering, you can use an explicit Comparator instead.


9.  Compare integral primitive fields using the relational operators < and >. For floating-point fields, use Double.compare or Float.compare in place of the relational operators, which do not obey the general contract for compareTo when applied to floating point values. For array fields, apply these guidelines to each element.

 

10.  If a class has multiple significant fields, the order in which you compare them is critical. You must start with the most significant field and work your way down. If a comparison results in anything other than zero (which represents equality), you’re done; just return the result. If the most significant fields are equal, go on to compare the next-most-significant fields, and so on. If all fields are equal, the objects are equal; return zero.

你可能感兴趣的:(Effective Java,comparable,comparator,compareTo)