黑马程序员技术交流社区
标题:
浅析传入自定义比较器之后,使用keySet遍历值为null的原因
[打印本页]
作者:
l493062120
时间:
2016-4-14 22:43
标题:
浅析传入自定义比较器之后,使用keySet遍历值为null的原因
直入主题,估计有很多同学出现过这样的问题就像下面的代码:
public class Test {
public static void main(String[] args) {
TreeMap<Integer, String> tm = new TreeMap<Integer, String>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2 == 0 ? 1 : o1 - o2;
}
});
tm.put(3, "a");
tm.put(1, "a");
tm.put(2, "a");
for (int i : tm.keySet()) {
System.out.println(i + "..." + tm.get(i));
}
}
}
复制代码
这段程序打印结果为:
1...null
2...null
3...null
复制代码
这是为什么?
原因就在 tm.get() 这个方法和比较器上,这个方法底层根据传入的键调用compare或者comparaTo方法去找集合中相同的键,当compare或者comparaTo方法返回0时,找到集合中的键,然后把对应的Value值返回给我们。
测试代码如下:
import java.util.Comparator;
import java.util.TreeMap;
public class Test {
public static void main(String[] args) {
TreeMap<Integer, String> tm = new TreeMap<Integer, String>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2 == 0 ? 1 : o1 - o2; //没有返回0的情况
}
});
tm.put(3, "a");
tm.put(1, "a");
tm.put(2, "a");
System.out.println(tm); //打印{1=a, 2=a, 3=a},说明value有值,确实存进去了
System.out.println(tm.get(3)); //打印null,get方法取不到value
}
}
复制代码
那么现在的问题就很明了了,如果自定义的比较器或者实现接口后的比较方法不能返回0,也就是说不去除重复的键的时候我们不能用keySe遍历得到键,再通过键去找值。只能用map.entry去遍历或者去掉重复的键也就是比较器方法要有返回0的情况。
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
public class Test {
public static void main(String[] args) {
TreeMap<Integer, String> tm = new TreeMap<Integer, String>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2 == 0 ? 1 : o1 - o2; //没有返回0的情况
}
});
tm.put(3, "a");
tm.put(1, "a");
tm.put(2, "a");
for (Map.Entry<Integer,String> me : tm.entrySet()) {
System.out.println(me.getKey() + "..." + me.getValue());
}
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2