黑马程序员技术交流社区

标题: 关于比较器的一点心得 [打印本页]

作者: 龚冼敏老师    时间: 2016-4-22 22:55
标题: 关于比较器的一点心得
本帖最后由 龚冼敏老师 于 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中存储重复元素!




作者: Q灬先生    时间: 2016-4-22 22:57
写的很详细~~~~
作者: Yoyoqiu    时间: 2016-4-22 23:06
太棒了   先收藏
作者: dtmacg    时间: 2016-4-27 10:30
详细 先收藏 慢慢看
作者: wen757862007    时间: 2016-4-27 11:13
好 楼主加油 棒
作者: r3562939    时间: 2016-4-27 12:33
怪不得 当时看源码没看下去 现在知道了
作者: chenghaoming    时间: 2016-4-27 12:52
好 楼主加油 棒
作者: 木辰    时间: 2016-4-27 14:30
不错不错,先收藏啦
作者: sxj    时间: 2016-4-27 14:52
我今天才学到 Collection集合中的ArrayList
作者: leo_yang    时间: 2016-4-27 17:11
不错不错,收藏
作者: 新人救济    时间: 2016-4-27 17:20
我看到io流了!!!!!!你们前面的方法都记住了吗?????


作者: jiang0409    时间: 2016-4-27 17:39
我看到io流了!!!!!!
作者: zhangzhibo    时间: 2016-4-27 17:42
加油!!!棒的
作者: 咆哮的杏鲍菇    时间: 2016-4-27 18:41
这个在我同学的面试题中有问过,谢谢分享
作者: 我想我等我期待    时间: 2016-4-27 18:41
看到朋友今天点招的压力!加油吧!
作者: and4576sdo    时间: 2016-4-27 20:04
感觉学习进入了休眠期!加油吧自己!
作者: ‘天依~蓝~    时间: 2016-4-27 20:08
赞666666666666
作者: danying    时间: 2016-4-27 20:40
赞赞。。。。。

作者: Vision.斌道    时间: 2016-4-27 21:04
作为一个正在学习的我,目标就是第一个大神,20万年薪,我也是可以做到的
作者: 天晴丶    时间: 2016-4-27 21:10
虽然还没学到 但是感觉好有用的样子
作者: feijiaqi    时间: 2016-4-27 21:13
很详细    非常感谢
作者: zh2016    时间: 2016-4-27 21:26
明白一些
作者: 我是黑    时间: 2016-4-27 21:40
轻松明白
作者: 代码人生?!    时间: 2016-4-27 22:15
打卡 javascript:;
作者: YYH7    时间: 2016-4-27 22:55
签个到

作者: chexinxin    时间: 2016-4-27 23:12
今天 学习了第三天基础课程 关于逻辑运算符,位运算符,if else switch
作者: 许霖彧    时间: 2016-4-27 23:14
今天 学习了第三天基础课程 关于逻辑运算符,位运算符,if else switch
作者: liuchenguangqnm    时间: 2016-4-27 23:16
收藏之,写的很好,需要再花点时间来看看
作者: 15900400069    时间: 2016-4-27 23:26
知识有限,蒙了,有待后续
作者: 为何帅    时间: 2016-4-27 23:28
正在基础班学习,还没学到呢,先收藏。
作者: zhoujiegun    时间: 2016-4-27 23:34
非常好,继续多发点
作者: 阿宾    时间: 2016-4-27 23:37
感谢楼主分享~
作者: huhemingtiancai    时间: 2016-4-27 23:42
总结多了对自己有好处的
作者: 冯领峰    时间: 2016-4-28 00:26
刚看到比较器这里,还在琢磨
作者: sunchuan    时间: 2016-4-28 01:01
听到比较器,感觉一头雾水
作者: LoveGG    时间: 2016-4-28 02:20
不理解,先截图记下.后来在研究
作者: ybqred    时间: 2016-4-28 06:45
一生只为黑马币!
作者: 长衫造纸农_    时间: 2016-4-28 08:35
每日一签
作者: 林明辉    时间: 2016-4-28 09:21
每日一签
作者: 拓跋伊祈    时间: 2016-4-28 09:30
谢谢分享~~~
作者: zzliuyang    时间: 2016-4-28 11:09
钱到了钱到了
作者: 纠结帝    时间: 2016-4-28 13:13
开心最重要,心态要平和,走你
作者: 九天玄妖    时间: 2016-4-28 13:26
学习了,初学时,把三元运算符的最后一个值写死了,不能去重复。
作者: jy6728228    时间: 2016-4-28 14:28
什么鬼,写了才知道已经有人写过了,教的时候说的不够清楚嘛
作者: sxj    时间: 2016-4-28 16:07
List  ——ArrayList  ——LinkedList——Vector         
作者: jy6728228    时间: 2016-4-28 16:25
什么鬼。我晚上出个==和equals的直播,看你还播不播
作者: xiaogui    时间: 2016-4-28 16:31
正在学习,留着慢慢消化
作者: success560    时间: 2016-4-28 18:12
正在学习,留着慢慢消化
作者: 布德鸟    时间: 2016-4-28 18:26
签里个到~
作者: sunchuan    时间: 2016-4-28 18:44
比较器是什么还没学到呢
作者: 晓路    时间: 2016-4-28 19:11
很不错的样子!!!{:2_32:}
作者: 忆々疯ラ萧萧    时间: 2016-4-28 19:55
多谢楼主点赞咯
作者: 酉良君    时间: 2016-4-28 20:03
写的很详细~~~~
作者: 359980621    时间: 2016-4-28 20:08
赞一个赞
作者: YYH7    时间: 2016-4-28 20:12
66666666666

作者: xiangzhuni886    时间: 2016-4-28 20:20
啊,老师,你以前很帅,现在更帅了
作者: 子豪_kTa58    时间: 2016-4-28 20:20
写的很详细,先收藏
作者: huhemingtiancai    时间: 2016-4-28 20:58
这个经常写的,还好
作者: 122754304    时间: 2016-4-28 20:59
qiandaoqiandao
作者: jiang0409    时间: 2016-4-28 21:04
日常点赞,另外这个用的多,写的也多
作者: tongtian    时间: 2016-4-28 21:31
加油加油加油加油加油加油
作者: 会飞的笨猫    时间: 2016-4-28 21:38
正在努力中
作者: jacobsnow    时间: 2016-4-28 21:46
come on!!baby
作者: 黑色千里马    时间: 2016-4-28 21:47
我只学到面向对象

作者: wufengqiao    时间: 2016-4-28 22:00
赞一个!!!!!!
作者: hmcxypzq    时间: 2016-4-28 22:12
javase  javaee  
作者: Bellriver    时间: 2016-4-28 22:13
写的很详细,必须赞一个
作者: yunmu    时间: 2016-4-28 22:14
多谢老师分享,点赞
作者: 今日微风    时间: 2016-4-28 22:17
多谢分享
作者: zhaokai123456    时间: 2016-4-28 22:41
明天要讲的课如何在时间不足的情况下高效率预习
作者: 天晴丶    时间: 2016-4-28 22:43
虽然还没看懂  但是感觉好流弊的感觉
作者: zhoujiegun    时间: 2016-4-28 23:03
哎哟妈呀,还得去练习了

作者: wang06125439    时间: 2016-4-28 23:05
。。。。。。。。。。。。。。。。。。。。
作者: chexinxin    时间: 2016-4-28 23:08
今天学习了 for(;;){}    初始化表达式; while(){}  do   循环体;while(){}
作者: lvdong22    时间: 2016-4-28 23:10
谢谢大哥了,小弟感激不尽
作者: lvdong22    时间: 2016-4-28 23:14
谢谢大哥了,小弟感激不尽
作者: lvdong22    时间: 2016-4-28 23:17
收藏,收藏,收藏
作者: yxpzzl    时间: 2016-4-28 23:27
收藏,慢慢看
作者: 随风而逸    时间: 2016-4-28 23:49
努力,加油
作者: lidongzhe    时间: 2016-4-29 00:12
讲的很细致
作者: lidongzhe    时间: 2016-4-29 00:17
太棒啦  讲的很细致...
作者: 我认识你    时间: 2016-4-29 00:23
顶一个!!!
作者: Ewig    时间: 2016-4-29 00:42
赞一个!
作者: YYH7    时间: 2016-4-29 00:58
签个到!!

作者: xiaoxiqq    时间: 2016-4-29 02:47
签个到

作者: zzliuyang    时间: 2016-4-29 09:45
签个到!!!!!
作者: BJing    时间: 2016-4-29 13:16
TreeSet和TreeMap昨天刚看到这里的视频
作者: wangfeng    时间: 2016-4-29 13:17
好东西,大爱之
作者: zhoubinjian    时间: 2016-4-29 13:27
非常重要,,。。
作者: zhoubinjian    时间: 2016-4-29 14:35
写的太棒了。。学习了
作者: 清凉    时间: 2016-7-4 08:15
写的好棒.支持一下
作者: perfect_class    时间: 2016-7-4 08:47
谢谢老师分享,收藏了!
作者: qinxuezilu1314    时间: 2016-7-4 09:24
学习了,谢谢楼主,好人一生平安
作者: 清凉    时间: 2016-7-5 07:57
好棒.支持一下
作者: 云袭    时间: 2016-7-5 10:44
大赞........




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2