TreeMap以及TreeSet的键能不能为null?Comparator比较器怎么使用?

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性质一样
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值