1. TreeMap的键可以为null吗?为什么?
答:一般来说TreeMap的键是不能为空的。因为在执行put方法存值时,会首先判断是否存在比较器,如果创建TreeMap实例时没有传入Comparator比较器,那么程序会对键进行判断,判断它是否为空,如果为空,就会抛出空指针异常。如果我们有特殊需求,是可以自己实现Comparator接口,并重写compare方法去处理掉比较对象为空的情况,这样做也是可以实现在TreeMap中存入一个空值的键的。
注意:TreeSet的底层是用TreeMap实现,即将TreeSet的值作为键存入TreeMap集合中,所以TreeSet存值时跟TreeMap一样的规则
源码:
TreeMap的put方法核心源码:
if (cpr != null) { //判断cpr比较器对象是否为空?
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null) //判断传入键是否为空
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
2.自定义一个比较器让TreeMap可以存入一个空值
//1. 定义一个学生类
static class Student{
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
//2. 自定义一个比较器
static class Comparator1 implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
if(o1 == null || o2 == null){ //处理掉比较对象为空值的情况
return -1;
}else{
if(o1.age>o2.age){
return 1;
}else if(o1.age==o2.age){
return 0;
}else{
return -1;
}
}
}
}
//3. 主方法
public static void main(String[] args) {
System.out.println("-------测试Comparator1比较器能否让TreeMap存入null键-------");
TreeMap<Student,String> map = new TreeMap<>(new Comparator1()); //创建TreeMap实例时传入比较器
map.put(new Student("张三",19),"喜欢吃鸡");
map.put(new Student("李四",16),"喜欢王者荣耀");
map.put(null,"马保国");
map.put(null,"神秘人");
System.out.println("1. 通过遍历Key去找Value:");
Set<Student> keys = map.keySet();
for (Student stu:keys){
System.out.println(stu+"——>"+map.get(stu));
}
System.out.println("2. 直接遍历Value:");
Collection<String> values = map.values();
for (String str:values){
System.out.println(str);
}
}
运行截图
结论:
- 正常情况下TreeMap是不能存入值为null的键的。
- 通过自定义比较器能让TreeMap存入一个值为null的键。
- 存入的值为null键对应的值不能通过通过它来获取,只能通过直接遍历。
TreeSet与TreeMap性质一样