【Effective Java】條12:考慮實現Comparable

如果自實現的類涉及到內在排序,譬如按字母排序或數字排序或日期排序的,強烈建議實現Comparable接口。

實現了Comparable接口的類,可以和許多的泛型算法以及集合進行協作。譬如,列表或數組中的元素實現了Comparable接口,則排序時可以直接調用Collections.sort(list)Arrays.sort(array)得到結果。

通用約定

JDK8文檔1中這樣描述Comparable接口的規定:
將一個對象和指定的對象比較排序,返回負數、零和正數分別表示小於、等於和大於指定的對象。如果兩個比較的對象之間類型不同,則拋出ClassCastException

假設sgn(expression)表示signum函數,僅返回-1、0和1。依據返回的結果:
1. 對應任何對象xy,都有sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
2. 對於任何對象xyz,如果x.compareTo(y) > 0 && y.compareTo(z) > 0,則x.compareTo(z) > 0
3. 對於任何對象xyz,如果x.compareTo(y) == 0,則sgn(x.compareTo(z)) == sgn(y.compareTo(z))
4. 強烈推薦,但不是必須要求。當x.compareTo(y) == 0時,x.equals(y)返回true

針對規則4,舉個反例:

public class BigDecimalDemo {

  public static void main(String[] args) {
    BigDecimal bigDecimal1 = new BigDecimal("4.0");
    BigDecimal bigDecimal2 = new BigDecimal("4.00");

    //return 0
    System.out.println(bigDecimal1.compareTo(bigDecimal2));
    //return false
    System.out.println(bigDecimal1.equals(bigDecimal2));
  }

}

接口使用

  1. User
package indi.latch.effective;

/**
 * Title: User
 * Description:
 *
 * @author lin.xu
 * @date 2018/5/2
 */
public class User implements Comparable<User> {
  private String name;
  private int age;
  private int sex;
  private String phone;

  public User() {
  }

  public User(String name, int age, int sex, String phone) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.phone = phone;
  }

  //Getter & Setter

  @Override
  public int compareTo(User o) {
    //先比較名字
    int nameCompare = name.compareTo(o.getName());
    if (0 != nameCompare) {
      return nameCompare;
    }

    //後比較年齡
    if (age != o.getAge()) {
      return age - o.getAge();
    }

    return 0;
  }

  @Override
  public String toString() {
    return "User{" +
        "name='" + name + '\'' +
        ", age=" + age +
        ", sex=" + sex +
        ", phone='" + phone + '\'' +
        '}';
  }
}
  1. UserCompareDemo
public class UserCompareDemo {

  public static void main(String[] args) {
    List<User> users = Lists.newArrayList(
        new User("acd", 11, 0, "12345678901", null),
        new User("abc", 10, 0, "12345678901", null)
    );

    Collections.sort(users);

    System.out.println(users);
  }

}
  1. 輸出結果
[User{name='abc', age=10, sex=0, phone='12345678901'}, User{name='acd', age=11, sex=0, phone='12345678901'}]

參考文檔

發佈了98 篇原創文章 · 獲贊 180 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章