【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'}]

参考文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现 `Comparable` 接口可以让对象具有可比性,方便进行排序等操作。在 Android 中,实现 `Comparable` 接口的方法与 Java 中相同。 首先,在类的声明中添加 `implements Comparable<类名>`,表示该类实现了 `Comparable` 接口,并指定了比较的类型为该类。 然后在类中实现 `compareTo` 方法,该方法返回一个整数值,表示当前对象与传入对象的大小关系。如果当前对象小于传入对象,返回负数;如果当前对象等于传入对象,返回0;如果当前对象大于传入对象,返回正数。 例如,假设有一个 `Person` 类,包含姓名和年龄两个属性,我们可以按照年龄大小比较两个人的大小关系。代码如下: ```java public class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Person person) { return this.age - person.getAge(); } } ``` 在 `compareTo` 方法中,我们比较当前对象的年龄属性与传入对象的年龄属性的大小关系。 使用时,我们可以将多个 `Person` 对象加入到一个 `List` 中,然后使用 `Collections.sort` 方法对其进行排序。例如: ```java List<Person> list = new ArrayList<>(); list.add(new Person("Alice", 20)); list.add(new Person("Bob", 18)); list.add(new Person("Charlie", 25)); Collections.sort(list); ``` 排序后,`list` 中的对象按照年龄从小到大排列。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值