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)赵信

TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树的更多相关文章

  1. TreeSet和TreeMap不能存放重复元素?能不能存放null?

    问题一:本来认为TreeMap不能存放重复元素?其实并非如此: 其实一般情况下是不允许存放重复元素的,但是它并非这么死板,在一些情况下是可以存放重复元素的,存了又会有引入其他问题. 问题二:能不能存放 ...

  2. TreeMap和TreeSet在排序时如何比较元素,Collections工具类中的sort()方法如何比较元素

    TreeSet和TreeMap排序时比较元素要求元素对象必须实现Comparable接口 Collections的sort方法比较元素有两种方法: 元素对象实现Comparable接口 实体类Dog ...

  3. 排序及重复元素去重的说明,TreeSet,HashSet

    先看下面一段代码: package 类集; import java.util.Set; import java.util.TreeSet; class Person{ private String n ...

  4. TreeSet和TreeMap中“相等”元素可能并不相等

    TreeSet和TreeMap元素之间比较大小是借助Comparator对象的compare方法. 但有些时候,即便compare()返回0也不意味着这两个元素直观上相同. 比如元素是二元组[a,b] ...

  5. 5.5(java学习笔记)TreeSet和TreeMap

    1.TreeMap TreeMap是可排序的Map类,使用这个类时,TreeMap会对存放的数据进行排序. 排序是根据key来排序的,排序规则是key实现comparable接口中的compareTo ...

  6. LinkedHashSet、Map、Map接口HashMap、Hashtable,TreeSet、TreeMap、如何选择使用集合实现类,Collections工具类

    一.Set接口实现类LinkedHashSet 实现继承图: 1.LinkedHashSet的全面说明 1) LinkedHashSet是 HashSet的子类 2) LinkedHashSet底层是 ...

  7. Java 集合类 TreeSet、TreeMap

    TreeMap和TreeSet的异同: 相同点: TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是拍好序的. TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之 ...

  8. 第40讲:Set、Map、TreeSet、TreeMap操作代码实战

    今天来看下set map的操作,让我们从代码出发 val data = mutable.Set.empty[Int] data ++= List(1,2,3)//在空set上加入列表 data += ...

  9. TreeSet与TreeMap浅解

    TreeSet与TreeMap的关系: 1.TreeSet 实际上就是用TreeMap来组织数据的,因为在TreeSet中保存了一个NavigableMap<e,Object>接口实例变量 ...

随机推荐

  1. java - day011 - 集合, ArrayList HashMap,HashSet, Iterator 接口, for-each 循环格式

    集合 ArrayList 丑数: 能被3,5,7整除多次, ArrayList     list 接口             | - ArrayList             | - Linked ...

  2. JAVA设计模式之单例模式(单件模式)—Singleton Pattern

    1.什么是单例模式? <Head First 设计模式>中给出如下定义:确保一个类只有一个实例,并提供一个全局访问点. 关键词:唯一实例对象. 2.单例模式的实现方式: 2.1 懒汉式 对 ...

  3. BZOJ 4316: 小C的独立集

    4316: 小C的独立集 思路:先将树上的转移做好.然后环上的转移就是强制最上面的的点选或者不选,然后在环上跑一遍转移就可以了. 代码: #pragma GCC optimize(2) #pragma ...

  4. MyBatis_动态sql_foreach_mysql下foreach批量插入的两种方式

    方法1: 笔记要点出错分析与总结工程组织数据库组织0.重新修改Bean类    修改1.定义接口 //批量插入 public void addEmps(@Param("emps") ...

  5. webpack 配置react脚手架(四):路由配置

    1. 由于 react-router 是集成了 react-router-dom 和 react-router-native的一起的,所以这里要使用的是 react-router-dom, 2. 安装 ...

  6. WebService在ssm框架中的简单应用

    WebService的概念 Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配 ...

  7. 跨站请求伪造(CSRF 或者 XSRF)与跨站脚本(XSS)

    跨站请求伪造 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 X ...

  8. vue 用户登录 路由拦截 vuex cookie

    功能: // 页面跳转后发送ajax请求给后端 请求详细信息 //点击课程推荐跳转到推荐课程详细 // 页面刚加载立即执行函数 = mounted <template> <div&g ...

  9. thymeleaf引入公共css、js

    有时候很多css文件是公共的,我们必须要在每个html文件中引入它们,其实我们可以利用Thymeleaf的模板布局,把这些css文件抽出来,同时如果有某个html文件专属的css文件,还可在引入模板的 ...

  10. learning scala pattern matching

    code: package com.aura.scala.day01 import scala.util.Random object patternMatching01 { def main(args ...