EffectiveJava——对于所有对象都通用的方法3

第12条:考虑实现Comparable接口

compareTo方法并没有在Object中声明,相反,它是Comparable接口中唯一的方法,comparaeTo方法不但允许简单的等同性比较,而且允许执行顺序比较,实现了Comparable接口,就表明它的实例具有内在的排序关系(natural ordering).为实现Comparable接口的对象数据排序就这么简单:

Arrays.sort(a)

对集合中的Comparable对象进行搜索,计算极限值以及自动维护也同样简单。一如下面程序依赖String实现了Comparable接口,去掉了命令行参数列表中的重复参数。并按字母顺序打出来

 public static void main(String[] args) {

        Set<String> strings = new TreeSet<>();
        for (int i = 0; i < 100; i++) {
            strings.add(String.valueOf(i % 5));
        }
        System.out.println(strings);
    }

打印结果:[0, 1, 2, 3, 4]

Java平台的所有值类(values classes)都实现了Comparable接口,如果你正在编写一个值类,它具有非常明显的内在排序关系,比如按字母排序,按数字排序…。,那几应该坚决的考虑实现这个接口:

public interface Comparable<T>{
   int compareTo(T t);
}

compareTo方法的通用约定与equals方法相似:
将这个对象与指定对象进行比较,当该对象小于,等于,或者大于指定的对象时候,分别返回一个负整数,零或者正数,如果由于指定的对象的类型而无法与该对象进行比较,那么抛出ClassCastException异常

sgn函数说明,它根据表达式的值为负数,零,正数分别返回-1,0,1;

实现者必须确保所有的x和y都满足

  • sgn(x.compareTo(y) == -y.compareTo(x))
  • x.compareTo(y) > 0 && y.compareTo(z) > 0 那么x.compareTo(z)必然大于0
  • x.compareTo(y)==0暗示着所有的z都满足sgn(x.compareTo(z)) == sgn(y.compareTo(z))
  • 强烈建议x.compareTo(y)==0 == (x.equals(y))但这并非绝对必要。一般来说实现了Comparable接口的类,若是违反了这个条件,都应该予以说明

最后一个约定是一个强烈的建议,而不是真的规则:
例如BigDecimal类,他的compareTo方法与equals不一致。

public static void main(String[] args) {
            BigDecimal decimal = new BigDecimal("1.332");
            BigDecimal decimal1 = new BigDecimal("1.3320");

            HashSet<BigDecimal> bigDecimals = new HashSet<>();
            bigDecimals.add(decimal);
            bigDecimals.add(decimal1);
            System.out.println(bigDecimals.size());


            TreeSet<BigDecimal> treeSet = new TreeSet<>();
            treeSet.add(decimal);
            treeSet.add(decimal1);
            System.out.println(treeSet.size());


        }
打印结果为: 2 1

与Comparable相关还有一个Comparator,具有类似的功能。

你可能感兴趣的:(EffectiveJava——对于所有对象都通用的方法3)