欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-21 14:59:00
1. TreeMap的键可以为null吗?为什么?答:一般来说TreeMap的键是不能为空的。因为在执行put方法存值时,会首先判断是否存在比较器,如果创建TreeMap实例时没有传入Comparator比较器,那么程序会对键进行判断,判断它是否为空,如果为空,就会抛出空指针异常。如果我们有特殊需求,是可以自己实现Comparator接口,并重写compare方法去处理掉比较对象为空的情况,这样做也是可以实现在TreeMap中存入一个空值的键的。注意:TreeSet的底层是用TreeMap实现,即将Tr...

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以及TreeSet的键能不能为null?Comparator比较器怎么使用?

结论:

  • 正常情况下TreeMap是不能存入值为null的键的。
  • 通过自定义比较器能让TreeMap存入一个值为null的键。
  • 存入的值为null键对应的值不能通过通过它来获取,只能通过直接遍历。
    TreeSet与TreeMap性质一样

本文地址:https://blog.csdn.net/weixin_44398687/article/details/109812851