本帖最后由 龚冼敏老师 于 2016-4-22 22:57 编辑 在整个java基础中,用到比较器的有两个地方,分别是TreeSet和TreeMap. 在学TreeSet的时候,有几道练习有特殊的要求,需要TreeSet实现保留重复元素并排序. 举例: 从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloitcast 程序打印:acehillostt,这个练习需要给TreeSet传入一个比较器,才能实现该需求. [size=0.83em]图片1.png (9.78 KB, 下载次数: 0) 下载附件 [url=]保存到相册[/url] [color=rgb(153, 153, 153) !important]6 天前 上传 结果,很多同学产生了一个错误的观念,他们认为,每次写比较器的时候,都需要保留其中的重复元素,所以每次写比较器的时候,都会习惯性的写成这样: 让比较器不会返回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中存储重复元素! |
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |