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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 龚冼敏老师 初级黑马   /  2016-4-22 22:55  /  6562 人查看  /  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 个回复

倒序浏览
Q灬先生 来自手机 中级黑马 2016-4-22 22:57:01
沙发
写的很详细~~~~
回复 使用道具 举报 1 0
太棒了   先收藏
回复 使用道具 举报 1 0
详细 先收藏 慢慢看
回复 使用道具 举报
好 楼主加油 棒
回复 使用道具 举报
怪不得 当时看源码没看下去 现在知道了
回复 使用道具 举报
好 楼主加油 棒
回复 使用道具 举报
木辰 中级黑马 2016-4-27 14:30:19
8#
不错不错,先收藏啦
回复 使用道具 举报
sxj 中级黑马 2016-4-27 14:52:05
9#
我今天才学到 Collection集合中的ArrayList
回复 使用道具 举报
不错不错,收藏
回复 使用道具 举报
我看到io流了!!!!!!你们前面的方法都记住了吗?????

回复 使用道具 举报
我看到io流了!!!!!!
回复 使用道具 举报
加油!!!棒的
回复 使用道具 举报
这个在我同学的面试题中有问过,谢谢分享
回复 使用道具 举报
看到朋友今天点招的压力!加油吧!
回复 使用道具 举报
感觉学习进入了休眠期!加油吧自己!
回复 使用道具 举报
赞666666666666
回复 使用道具 举报
赞赞。。。。。
回复 使用道具 举报
作为一个正在学习的我,目标就是第一个大神,20万年薪,我也是可以做到的
回复 使用道具 举报
虽然还没学到 但是感觉好有用的样子
回复 使用道具 举报
12345下一页
您需要登录后才可以回帖 登录 | 加入黑马