zoukankan      html  css  js  c++  java
  • TreeSet和TreeMap不能存放重复元素?能不能存放null?

    问题一:本来认为TreeMap不能存放重复元素?其实并非如此;
    其实一般情况下是不允许存放重复元素的,但是它并非这么死板,在一些情况下是可以存放重复元素的,存了又会有引入其他问题。
    问题二:能不能存放null呢?正常情况下是不能的,会报异常,但是经过一些处理后是可以的。
    解答问题一:
    1、存放元素时,TreeMap实现外部比较器接口Comparator,并重写其compare方法,当判断元素重复时,强制compare方法返回一个非0的数,就可以将重复元素存入;

    TreeMap<Integer,String> tree = new TreeMap<Integer,String>(new Comparator<Integer>(){
    @Override
    public int compare(Integer o1, Integer o2) {
    if(o1.equals(o2))
    return 1;
    else
    return o1-o2;
    }
    });

    这种是通过外部比较器进行排序,即是,不通过元素自身的方法来比较,而通过集合实现比较器接口来进行排序。上面代码,通过外部比较器中重写compare方法,判断其返回值来确定排序位置,判断结果有三种:(一)大于0,(二)小于0,(三)等于0;大于0时,表示o1比o2大,因此要排在后面,,小于0时,表示o1比o2小,因此要排在前面,等于0时,集合会认为二者相等,即已经存在此元素了,不再存储(从这一点可以反映出TreeMap集合框架的防止元素重复的机制),但是会对值进行更新(我们的重点不在值)。~~这一点就体现了TreeMap集合的灵活性了,我们如果想存入重复元素,那么就可以控制compare方法的返回值,来达到目的。这样是有效的→→↓↓;
    但是???问题来了,比如我们在compare中重写,判断两个元素一样是,强制返回1,元素是存进去了,可是我们在调用get方法去拿出这个元素和其值时,就出问题了,拿到的永远是null,也就是找不到这个元素!不按常规出牌总是要付出代价的,为什么呢??查看底层代码,我们可以发现,get方法取元素同样是根据比较器来取,调用compare方法查找,直到查找到能让compare方法返回0的元素,就判断,这个元素就是我们要找的元素,就将它的值取出来,如果查完了也没有返回0,那么就认为集合中不存在这个键,返回null!
    Demo:

    TreeMap<Integer,String> tree = new TreeMap<Integer,String>(new Comparator<Integer>(){
    @Override
    public int compare(Integer o1, Integer o2) {
    if(o1.equals(o2))
    return 1;
    else
    return o1-o2;
    }
    });
    tree.put(1, "唐僧");
    tree.put(2, "李白");
    tree.put(5, "白居易");
    tree.put(3, "孙悟空");
    tree.put(2, "李黑");
    System.out.println(tree);
    System.out.println("get(1):"+tree.get(1)+" get(2)"+tree.get(2));

    输出:
    {1=唐僧, 2=李白, 2=李黑, 3=孙悟空, 5=白居易}
    get(1):null get(2)null

    将compare方法中的equles判断返回值改为0,输出:
    {1=唐僧, 2=李黑, 3=孙悟空, 5=白居易}
    get(1):唐僧 get(2)李黑

    同样的道理,TreeSet其实就是通过TreeMap来实现的,那么其也响应的特性。

    —————————————————————————–
    解答问题二:
    能不能存放null呢?是可以存放的,但是要避免一个问题,避免出现空指针异常,这个问题是很容易出现的;
    如果不实现Comparator接口,那么一定会报出空指针异常(有人会问了,不是还可以用元素实现内部比较器接口吗?是可以实现接口,但是实现了后,存入一个空元素也没法调用它里面的compareTo方法。。),如果实现了Comparator接口,通过适当的写法,时可以避免出现空指针异常,并且顺利的将元素存入和取出:

    TreeMap<Integer,String> tree = new TreeMap<Integer,String>(new Comparator<Integer>(){
    @Override
    public int compare(Integer o1, Integer o2) {
    if(o1 !=null&&o2!=null)
    return o1-o2;
    else if(o1 == null&&o2 != null){
    return -1;
    }else if(o1!=null&&o2==null)
    return 1;
    else
    return 0;
    }
    });
    tree.put(1, "唐僧");
    tree.put(2, "李白");
    tree.put(5, "白居易");
    tree.put(3, "孙悟空");
    tree.put(2, "李黑");
    tree.put(null, "赵信");
    System.out.println(tree);
    System.out.println("get(1):"+tree.get(1)+" get(2)"+tree.get(null));

    输出:
    {null=赵信, 1=唐僧, 2=李黑, 3=孙悟空, 5=白居易}
    get(1):唐僧 get(2)赵信
    ---------------------
    作者:TT海浅
    来源:CSDN
    原文:https://blog.csdn.net/u010698072/article/details/55255073
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    论文-Deep Residual Learning for Image Recognition
    网易2017秋招编程题集合-牛客网
    论文-GoogleNet : Going Deeper with Convolutions
    腾讯2016研发工程师编程题-牛客网
    网易2017春招笔试真题编程题集合-牛客网
    剑指offer-把二叉树打印成多行
    剑指offer-翻转单词顺序列
    剑指offer-和为S的连续正数序列
    Java [leetcode 21]Merge Two Sorted Lists
    Java [leetcode 20]Valid Parentheses
  • 原文地址:https://www.cnblogs.com/moxiaotao/p/10227854.html
Copyright © 2011-2022 走看看