A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 龚冼敏老师 初级黑马   /  2016-4-22 22:55  /  6564 人查看  /  94 人回复  /   4 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 龚冼敏老师 于 2016-4-22 22:57 编辑

在整个java基础中,用到比较器的有两个地方,分别是TreeSetTreeMap.
在学TreeSet的时候,有几道练习有特殊的要求,需要TreeSet实现保留重复元素并排序.
举例:
从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloitcast
程序打印:acehillostt,这个练习需要给TreeSet传入一个比较器,才能实现该需求.

结果,很多同学产生了一个错误的观念,他们认为,每次写比较器的时候,都需要保留其中的重复元素,所以每次写比较器的时候,都会习惯性的写成这样:

让比较器不会返回0. 这个比较器使用在TreeSet中并不会出现太大的问题,最多就是有重复元素,但是用在TreeMap中就有一个很大的问题出现了.
例如: 定义一个TreeMap,键为String,存储学生姓名,值为Integer,存储学生年龄,需求按字符串字典顺序的倒序排序.
正常情况下,代码应该如下:

但是学生习惯性保留重复元素,写成了这样:

存储元素的过程是没有问题的:



但是在通过键来获取对应的值的时候就出问题了:

结果是这样的:


得到的值全部是null

这是为什么呢?

这就要分析一下TreeMap集合中的get(Object key)方法了,看看它是如何根据key返回value.
首先,通过查看源码:

发现它其实是调用了一个叫getEntry()的方法,我们再跟进去看看:

这里面第一句代码,就是判断是否有比较器,如果有,调用getEntryUsingComparator(key)这个方法,很明显是有比较器的,所以我们不用再看下面的代码了,直接进入getEntryUsingComparator(key)方法:

从红线框出来的地方可以看得出来,只有当比较器返回0的时候,才会返回p这个对象.而之前我们传进来的比较器永远不会返回0,所以,get方法自然也就获取不到任何的值了,只能得到null.
SO,建议大家在写比较器的时候,不要盲目的根据从前的经验来写,一定要根据需求来.更加不要在TreeMap中存储重复元素!



评分

参与人数 1技术分 +2 收起 理由
r1503882525 + 2 赞一个!

查看全部评分

94 个回复

正序浏览
大赞........
回复 使用道具 举报
好棒.支持一下
回复 使用道具 举报
qinxuezilu1314 来自手机 中级黑马 2016-7-4 09:24:07
92#
学习了,谢谢楼主,好人一生平安
回复 使用道具 举报
谢谢老师分享,收藏了!
回复 使用道具 举报
写的好棒.支持一下
回复 使用道具 举报
写的太棒了。。学习了
回复 使用道具 举报
非常重要,,。。
回复 使用道具 举报
好东西,大爱之
回复 使用道具 举报
BJing 中级黑马 2016-4-29 13:16:12
86#
TreeSet和TreeMap昨天刚看到这里的视频
回复 使用道具 举报
签个到!!!!!
回复 使用道具 举报
签个到
回复 使用道具 举报
YYH7 中级黑马 2016-4-29 00:58:05
83#
签个到!!
回复 使用道具 举报
Ewig 中级黑马 2016-4-29 00:42:15
82#
赞一个!
回复 使用道具 举报
顶一个!!!
回复 使用道具 举报
太棒啦  讲的很细致...
回复 使用道具 举报
讲的很细致
回复 使用道具 举报
努力,加油
回复 使用道具 举报
收藏,慢慢看
回复 使用道具 举报
收藏,收藏,收藏
回复 使用道具 举报
谢谢大哥了,小弟感激不尽
回复 使用道具 举报
12345下一页
您需要登录后才可以回帖 登录 | 加入黑马