Effective Item-Implement comparable interface with care

Source: Internet
Author: User
Tags comparable

The class implements the comparable interface to indicate that the class instance itself has an intrinsic sort relationship (natural ordering).
Therefore, the class can collaborate with many generic algorithms and collection implementations.
And the only way we need to implement the comparable interface--compareTo.


The following rules are relevant:

    • SGN (X.compareto (y)) =-SGN (Y.compareto (x))
    • (X.compareto (y) >0 && y.compareto (z) >0) X.compareto (z) >0
    • X.compareto (y) = = 0 sgn (X.compareto (z)) = = SGN (Y.compareto (z))
    • Suggested X.compareto (y) = = 0 O'Clock x.equals (y)


The fourth is not necessary, but it is worth knowing.
Equivalence comparisons in some ordered structures may use compareto rather than equals.
In view of this situation, we need to make compareto and equals compatible.
However, special cases do not have to do this, such as in the BigDecimal class new BigDecimal("1.00") and new BigDecimal("1.0") , the equals result for the False,compareto result is 0.


There are different methods of comparison for different types of field in a class:

    • Non-floating base type directly using relational operators
    • Floating-point types Use the Compare method of the encapsulated class
    • The reference type can call CompareTo recursively, providing the displayed comparator if a field is found to have not implemented comparable.
    • The array type applies the above rules to each element.


Typically, for a class's key field, we can prioritize them according to their critical level.
From the most critical start-by-comparison, the results are returned without a 0 result.


Here is an example:

Making PhoneNumber comparable-pages 65-66package org.effectivejava.examples.chapter03.item12;import Java.util.navigableset;import java.util.random;import Java.util.treeset;public Final class PhoneNumber implements    Cloneable, comparable<phonenumber> {private final short areacode;    private final short prefix;    Private final short linenumber;        Public PhoneNumber (int areacode, int prefix, int. linenumber) {Rangecheck (AreaCode, 999, "area code");        Rangecheck (prefix, 999, "prefix");        Rangecheck (linenumber, 9999, "line number");        This.areacode = (short) AreaCode;        This.prefix = (short) prefix;    This.linenumber = (short) linenumber; } private static void Rangecheck (int arg, int max, String name) {if (Arg < 0 | | arg > MAX) thr    ow new IllegalArgumentException (name + ":" + arg);        } @Override public boolean equals (Object o) {if (o = = this) return true; if (! ( o instanceof PhoneNumber)) return false;        PhoneNumber pn = (phonenumber) o;    return Pn.linenumber = = LineNumber && Pn.prefix = = Prefix && pn.areacode = areacode;        } @Override public int hashcode () {int result = 17;        result = * result + AreaCode;        result = * result + prefix;        result = * result + linenumber;    return result;        } @Override Public PhoneNumber clone () {try {return (PhoneNumber) Super.clone (); } catch (Clonenotsupportedexception e) {throw new Assertionerror ();//Can ' t happen}}//Works Fine, but can is made faster//public int compareTo (PhoneNumber pn) {////Compare area codes//if (AreaCode & Lt    Pn.areacode)//return-1;    if (AreaCode > Pn.areacode)//return 1;    //area codes is equal, compare prefixes//if (prefix < pn.prefix)//return-1; if (prefix > Pn.prefix)// return 1; //area codes and prefixes is equal, compare line numbers//if (LineNumber < Pn.linenumber)//return    -1;    if (linenumber > Pn.linenumber)//return 1; return 0; All fields is equal//} public int compareTo (PhoneNumber pn) {//Compare area codes int AreaCode        Diff = Areacode-pn.areacode;        if (Areacodediff! = 0) return areacodediff;        Area codes is equal, compare prefixes int prefixdiff = Prefix-pn.prefix;        if (Prefixdiff! = 0) return prefixdiff;    Area codes and prefixes is equal, compare line numbers return linenumber-pn.linenumber;         } public static void Main (string[] args) {navigableset<phonenumber> s = new treeset<phonenumber> ();        for (int i = 0; i < i++) S.add (Randomphonenumber ());    System.out.println (s);    } private static final random rnd = new Random (); private static PhoneNumber Randomphonenumber () {return new PhoneNumber ((short) rnd.nextint (+), (short) Rnd.nex    TInt (+), (short) Rnd.nextint (10000)); }}


The field in the example above is non-floating-point base type, so the author optimizes it.
Since CompareTo only needs the sign of the return value, not the size, the difference is used instead of the logical comparer.


However, this usage should be noted that the type of field may not accommodate the difference of two values.
Like integer.max_value-(-1) or integer.min_value-1 or something like that.
This behavior does not occur if you can guarantee that the field value will not be negative.

Effective Item-Implement comparable interface with care

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.