资讯专栏INFORMATION COLUMN

java comparable 和 comparator

why_rookie / 2848人阅读

摘要:一内部排序接口实现该接口的类,支持自然排序内排序。方法与方法不一致。在有序集合看来和是相等的,因此第个键无法被添加到集合中。

一、Comparable(内部排序接口)

实现该接口的类,支持自然排序(内排序)。Arrays.sort(Object[])和Collection.sort(Object[])要求对象必须实现Comparable接口

文档中指出:

如果该对象大于指定对象,返回正整数

如果该对象等于指定对象,返回0

如果该对象小于指定对象,返回负整数

建议(x.compareTo(y)==0) == x.equals(y)

e.compareTo(null) 应该抛出NullPointerException

键a和b被添加到没有指定显示比较器的有序集合中。if(!a.equals(b) && a.compareTo(b))(eqauls方法与compareTo方法不一致)。在有序集合看来a和b是相等的,因此第2个键无法被添加到集合中。

针对第6点可以举个例子:
BigDecimal类的compareTo 与 equals 方法不一致。

public static void main(String[] args) {
        Map map = new HashMap();
        BigDecimal b1 = new BigDecimal(1.0);
        BigDecimal b2 = new BigDecimal(1.00);
        map.put(b1,"c1");
        map.put(b2,"c2");
        System.out.println(map.get(b1) + " " + map.get(b2)); // 输出 c1、c2
        TreeSet set = new TreeSet();
        set.add(b1);
        set.add(b2);
        for(BigDecimal b : set) {
            System.out.println(b.floatValue()); // 只打印出1.0
        }
    }

HashMap通过 hashCode + equals 方法进行比较。 TreeSet 通过 compareTo进行比较。

在effctiveJava中 指出,Comparable接口,具有与equals方法一样的自反、传递、对称。所以同样与equals具有同样的特征:
没有一种简单的方法可以做到,在扩展一个新的可实例化的类时,既增加了新的特征,又保持了compareTo的约定(见我的文章)

对于如何编写compareTo方法,effectivejava中,同样给出了以下建议。并且推荐,自定义的类,可以考虑实现Comparable接口

实参为null,compareTo方法应抛出NullPointerException

参数不合适,应抛出ClassCastException

比较对象引用域,通过递归比较

如果对象有多个域,则从最重要的域开始比较

compareTo没有指定返回值的大小,而只是指定返回值的符号,可利用这点进行优化

例子:

public int compareTo(Object obj) {
        if(obj == null) {
            throw new NullPointerException(); // 满足第1点
        }
        if(!(obj instanceof MyComparable)) {
            throw new ClassCastException(); // 满足第2点
        }
        MyComparable o = (MyComparable) obj;
        int x = o.p.compareTo(p);// p 是一个对象 ,满足第3、4点
        if(x == 0) {
            return o.y - y;  // y 是个int型, 满足第5点,
           //对于第5点请注意,确保 o.y -y 不会溢出!!!
        }
        return x;
    }
二、Comparator(外部比较器)

可自己制定比较规则。在TreeSet中有应用,TresSet利用Comparator接口实现模板设计模式

文档中指出:

如果该对象大于指定对象,返回正整数

如果该对象等于指定对象,返回0

如果该对象小于指定对象,返回负整数

建议(x.compareTo(y)==0) == x.equals(y)

必须确保关系的传递性。即compare(x,y) > 0 且 compare(y,z) > 0,那么 compare(x,z) > 0

在本人看来,Comparable 与 Comparator 差别不大

疑问:那么Comparator具体的使用在什么地方呢?

JAVA API 的String 类 默认实现了Comparable接口,有默认的排序方式,但是如果我们想使用自己的排序方式呢?比如按照长度排序,那么就可以使用Comparator接口了。

class LengthComparator implements Comparator {
    @Override
    public int compare(String o1, String o2) {
        return o1.length() - o2.length();
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70543.html

相关文章

  • Java Comparable vs Comparator

    摘要:和方法可以对数组进行排序,但是这种方法排序要求对象所在的类必须实现接口,此接口用于指定排序规则如果一个类已经开发完成,但是在此类建立的初期并没有实现接口,此时肯定是无法进行对象排序操作的,所以为了解决这个问题,定义了另一个比较器的操 Collections.sort() 和 Arrays.sort()方法可以对Object数组进行排序,但是这种方法排序要求对象所在的类必须实现Compa...

    KitorinZero 评论0 收藏0
  • Comparable and Comparator

    摘要:中的一切类都是继承于,在中实现了函数所以,其它所有的类也相当于都实现了该函数。是比较和的大小。返回负数,意味着比小返回零,意味着等于返回正数,意味着大于。 Comparable Comparable 是排序接口。 Collection.sort() 和Arrays.sort()都支持可以排序实现Comparable接口的类的对象的List列表(或数组) 换而言之, 如果数组或列表想支持...

    Barrior 评论0 收藏0
  • Java™ 教程(对象排序)

    对象排序 List l可以如下排序。 Collections.sort(l); 如果List包含String元素,它将按字母顺序排序,如果它由Date元素组成,它将按时间顺序排序,这是怎么发生的?String和Date都实现了Comparable接口,Comparable实现为类提供了自然的顺序,允许该类的对象自动排序,下表总结了一些实现Comparable的更重要的Java平台类。 类 自然...

    Chao 评论0 收藏0
  • 如何理解java里的ComparatorComparable

    摘要:,又名比较器,是为了比较两个对象的大小而抽象出的一个接口。在排序的时候常需要实现这个接口来定制比较规则。若函数的返回值大于,那么在排序后会将放在的后面。 Comparator,又名比较器,是为了比较两个对象的大小而抽象出的一个接口。在排序的时候常需要实现这个接口来定制比较规则。 但是很多人用的时候不清楚该如何使用这个接口,下面我就讲一下这个接口的正确使用方法!这个接口里有一个必须实现的...

    sydMobile 评论0 收藏0
  • Java ComparatorComparable辨析

    摘要:与辨析声明文章均为本人技术笔记,转载请注明出处比较三种状态根据需求定义序升序降序返回负数,表示比较两元素满足序,无须调整,返回,表示比较两元素相等,无须调整位置,返回正数,表示比较两元素不满足序,按序调整位置对象内部排序源码继承接口的对象必 Comparator与Comparable辨析 声明 文章均为本人技术笔记,转载请注明出处:[1] https://segmentfault.co...

    wenhai.he 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<