博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java:实现比较接口时,应该全面的进行各种情况的比较
阅读量:2426 次
发布时间:2019-05-10

本文共 2550 字,大约阅读时间需要 8 分钟。

Java中实现类的自定义比较功能,可以通过实现Comparable,或者Comparator,前者是一个内比较器,后者是一个外比较器,但无论是哪种在实现比较方法时,都应该充分考虑各种情况:

  1. 比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数
  2. 比较者等于被比较者,那么返回0
  3. 比较者小于被比较者,那么返回负整数

假如只考虑了其中的两种情况,会有什么影响了?

Bad Case

考虑下面的实现,在调用TreeSet或者TreeMap的containsKey时会有什么影响了?

@Data@EqualsAndHashCodeclass ImgSize implements Comparable
{ private int width; private int height; public ImgSize(int width, int height) { this.width = width; this.height = height; } @Override public int compareTo(ImgSize obj) { if (this.width < obj.width) { return -1; } else if (this.height < obj.height) { return -1; } else { return 1; } }}
Map
pics = new TreeMap<>(); pics.put(new ImgSize(3,4), "Pic_A"); pics.put(new ImgSize(1,3), "Pic_B"); pics.put(new ImgSize(1,2), "Pic_C"); for(Map.Entry entry:pics.entrySet()) { System.out.println(entry); } System.out.println(pics.containsKey(new ImgSize(1,2)));// 输出ImgSize(width=1, height=2)=Pic_CImgSize(width=1, height=3)=Pic_BImgSize(width=3, height=4)=Pic_Afalse

尽管实现了排序功能,但是containsKey方法返回的false,这是为何了?不妨看下它的实现

public boolean containsKey(Object key) {        return getEntry(key) != null;    }final Entry
getEntry(Object key) { // Offload comparator-based version for sake of performance if (comparator != null) return getEntryUsingComparator(key); if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable
k = (Comparable
) key; Entry
p = root; while (p != null) { int cmp = k.compareTo(p.key); if (cmp < 0) p = p.left; else if (cmp > 0) p = p.right; else return p; } return null; }

本以为containsKey是根据hashCode和equals方法来实现的,已lombok注解已经实现了这两个方法,然而containsKey实际是根据比较器实现的,如果自定义的比较器中没有相等的实现,containsKey是不会正确返回预期的结果的。

修正

@Data@EqualsAndHashCodeclass ImgSize implements Comparable
{ private int width; private int height; public ImgSize(int width, int height) { this.width = width; this.height = height; } @Override public int compareTo(ImgSize obj) { if (this.width < obj.width) { return -1; } else if (this.width == obj.width) { return (this.height < obj.height ? -1:(this.height == obj.height ? 0 : 1)); } else { return 1; } }}

转载地址:http://skbmb.baihongyu.com/

你可能感兴趣的文章
一周内咸鱼疯转 2.4W 次,最终被所有大厂封杀!
查看>>
关于鸿蒙 2.0,那些开发者不知道的一切
查看>>
Google 排名第一的语言,引数十万人关注:搞定它,技术大牛都甘拜下风
查看>>
JavaScript 爆红后,微软为何还要开发 TypeScript?
查看>>
软件开发行业,年轻与大龄程序员的生存现状
查看>>
王者荣耀活动精选 Blink 第二弹来袭!
查看>>
打开数“智”化之门,一字之差带来的思考
查看>>
阿里技术人的成长路径是什么?
查看>>
你值得拥有!更省钱地完成数据监听
查看>>
漫画 | TCP,一个悲伤的故事
查看>>
张一鸣无圈胜破圈?
查看>>
抓紧!抓紧!CSDN年终重榜福利来了~人手一份,快来投稿!!
查看>>
干货! AI 推断解决方案栈 Vitis AI 全流程独家解析
查看>>
真相了 | 敲代码时,程序员戴耳机究竟在听什么?
查看>>
回首互联网十年,我们能从八次烧钱大战中学到什么
查看>>
漫画:如何辨别二逼互联网公司!?
查看>>
麒麟信安面向场景化创新,赋能openEuler商业验证
查看>>
王者又连跪了?快让 AI 帮你上分!
查看>>
1 分钟带你认识从 "�" 到 "锟斤拷"
查看>>
3 年培养 10 万“码农”,郑州推出“码农计划”
查看>>