Java 集合类 TreeSet、TreeMap
TreeMap和TreeSet的异同:
相同点:
- TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是拍好序的。
- TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之间共享,不过可以使用方法Collections.synchroinzedMap()来实现同步
- 运行速度都要比Hash集合慢,他们内部对元素的操作时间复杂度为O(logN),而HashMap/HashSet则为O(1)。
不同点:
- 最主要的区别就是TreeSet和TreeMap非别实现Set和Map接口
- TreeSet只存储一个对象,而TreeMap存储两个对象Key和Value(仅仅key对象有序)
- TreeSet中不能有重复对象,而TreeMap中可以存在
TreeSet的是NavigableSet的实现类,NavigableSet继承了SortedSet接口,SortedSet是Set的子接口;
1 public class TreeSet<E> extends AbstractSet<E>
2 implements NavigableSet<E>, Cloneable, java.io.Serializable
3 {
4 /**
5 * The backing map.
6 */
7 private transient NavigableMap<E,Object> m;
8
9 // Dummy value to associate with an Object in the backing Map
10 private static final Object PRESENT = new Object();
11
12 /**
13 * Constructs a set backed by the specified navigable map.
14 */
15 TreeSet(NavigableMap<E,Object> m) {
16 this.m = m;
17 }
18
19 /**
20 * Constructs a new, empty tree set, sorted according to the
21 * natural ordering of its elements. All elements inserted into
22 * the set must implement the {@link Comparable} interface.
23 * Furthermore, all such elements must be <i>mutually
24 * comparable</i>: {@code e1.compareTo(e2)} must not throw a
25 * {@code ClassCastException} for any elements {@code e1} and
26 * {@code e2} in the set. If the user attempts to add an element
27 * to the set that violates this constraint (for example, the user
28 * attempts to add a string element to a set whose elements are
29 * integers), the {@code add} call will throw a
30 * {@code ClassCastException}.
31 */
32 public TreeSet() {
33 this(new TreeMap<E,Object>());
34 }
35 .......
36 }
由上面的TreeSet的源码可以看出,TreeSet的底层实现是通过TreeMap实现的,而TreeMap的底层又是如何实现的呢?
1 public TreeMap() {
2 comparator = null;
3 }
4
5 public TreeMap(Comparator<? super K> comparator) {
6 this.comparator = comparator;
7 }
8 .....(其他构造方法不一一列举)
9 //这里列举put方法详细讲解
10 public V put(K key, V value) {
11 Entry<K,V> t = root;
12 if (t == null) {
13 compare(key, key); // type (and possibly null) check
14
15 root = new Entry<>(key, value, null);
16 size = 1;
17 modCount++;
18 return null;
19 }
20 int cmp;
21 Entry<K,V> parent;
22 // split comparator and comparable paths
23 Comparator<? super K> cpr = comparator;
24 if (cpr != null) {
25 do {
26 parent = t;
27 cmp = cpr.compare(key, t.key);
28 if (cmp < 0)
29 t = t.left;
30 else if (cmp > 0)
31 t = t.right;
32 else
33 return t.setValue(value);
34 } while (t != null);
35 }
36 else {
37 if (key == null)
38 throw new NullPointerException();
39 Comparable<? super K> k = (Comparable<? super K>) key;
40 do {
41 parent = t;
42 cmp = k.compareTo(t.key);
43 if (cmp < 0)
44 t = t.left;
45 else if (cmp > 0)
46 t = t.right;
47 else
48 return t.setValue(value);
49 } while (t != null);
50 }
51 Entry<K,V> e = new Entry<>(key, value, parent);
52 if (cmp < 0)
53 parent.left = e;
54 else
55 parent.right = e;
56 fixAfterInsertion(e);
57 size++;
58 modCount++;
59 return null;
60 }
从上面的TreeMap的两个构造方法和插入方法可以看出当第一次插入时,返回null,插入值不同时返回null;否则返回值不为null;这里需要注意以下几点:
1、创 建TreeSet或者TreeMap时候采用有参构造函数并且参数是Comparator时候,参数必须是Comparator的实现子类;而利用无参构 造函数时,向TreeSet或者TreeMap添加元素是需要特别注意所添加的对象必须是实现了Comparable接口的子类否则会报错(对象类型 cannot be cast to java.lang.Comparable),这也是TreeMap的put方法中实现的原因,这是多态的表现,父类对象指向子类引用;
Comparable<? super K> k = (Comparable<? super K>) key;
2、由于TreeSet和TreeMap的底层都是树形结构,而且每一个节点的对象是Entry对象
1 K key;
2 V value;
3 Entry<K,V> left = null;
4 Entry<K,V> right = null;
5 Entry<K,V> parent;
这是Entry的结构,是一个类似链表节点的树形结构;
3、TreeSet和TreeMap的底层都是树形结构是一个二叉查找树,并且是一个红黑平衡树,实现方法:
fixAfterInsertion(e);
Java 集合类 TreeSet、TreeMap的更多相关文章
- java集合类之TreeMap
转自:http://blog.csdn.net/chenssy/article/details/26668941 TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的 ...
- java集合类TreeMap和TreeSet
看这篇博客前,可以先看下下列这几篇博客 Red-Black Trees(红黑树) (TreeMap底层的实现就是用的红黑 ...
- 关于java集合类TreeMap的理解(转)
概要 这一章,我们对TreeMap进行学习. 转载请注明出处:http://www.cnblogs.com/skywang12345/admin/EditPosts.aspx?postid=33109 ...
- Java集合类--温习笔记
最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...
- 做JavaWeb开发不知Java集合类不如归家种地
Java作为面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储.但是使用数组存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容 ...
- 【转载】Java集合类Array、List、Map区别和联系
Java集合类主要分为以下三类: 第一类:Array.Arrays第二类:Collection :List.Set第三类:Map :HashMap.HashTable 一.Array , Arrays ...
- 摘抄转载前辈们的Java集合类总结
本文摘自 Blue Sky:http://www.cnblogs.com/hubcarl JAVA 集合类介绍和使用 类关系示意图Iterable(接口) │ └--Collection (接口) ├ ...
- Java集合类: Set、List、Map、Queue使用场景梳理
本文主要关注Java编程中涉及到的各种集合类,以及它们的使用场景 相关学习资料 http://files.cnblogs.com/LittleHann/java%E9%9B%86%E5%90%88%E ...
- Java 集合类详解(含类图)
0.参考文献 此图中蓝色为抽象类.深红色表示接口(Arrays除外).绿色表示具体容器类 1.java集合类图 1.1 1.2 上述类图中,实线边框的是实现类,比如ArrayList,LinkedLi ...
随机推荐
- C#进阶系列——DDD领域驱动设计初探(三):仓储Repository(下)
前言:上篇介绍了下仓储的代码架构示例以及简单分析了仓储了使用优势.本章还是继续来完善下仓储的设计.上章说了,仓储的最主要作用的分离领域层和具体的技术架构,使得领域层更加专注领域逻辑.那么涉及到具体的实 ...
- 【knockout】ko绑定click事件传多个参数,
源:http://knockoutjs.com/documentation/event-binding.html <a href="javascript:;" class=& ...
- 软件工程(FZU2015)赛季得分榜,第10回合(alpha冲刺)
目录 第一回合 第二回合 第三回合 第四回合 第五回合 第6回合 第7回合 第8回合 第9回合 第10回合 第11回合 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分 ...
- C#中中文编码的问题(StreamWriter和StreamReader默认编码)
在使用StreamWriter和StreamReader时产生了这样的疑问,在不指定的情况下,他们使用什么编码方式? 查看MSDN,请看下图: 注意红色区域 这让我以为构造函数参数不同时使用不一样的 ...
- CM12.1/13.0编译教程
环境搭建 1.安装64位Ubuntu系统(实体安装.虚拟机安装均可) 注意:要求机器至少4G内存(虚拟机至少分配4G内存),硬盘至少100G空间(源码20G+,编译后整个目录约60~70G) 安装方法 ...
- 在canvas中使用html元素
让div悬浮于canvas之上 使用z-index控制层及顺序 慕课网canvas demo <div id="canvas-wrapper"> <canva ...
- javascript变量声明 及作用域
javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 java ...
- Bzoj1096 [ZJOI2007]仓库建设
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4193 Solved: 1845 Description L公司有N个工厂,由高到底分布在一座山上. ...
- Day1-python基础1
本次学习内容 Python介绍 发展史 版本选择 install 第一个程序hello world 字符编码及注释 变量 用户输入 表达式if...else 一.Python介绍 1)Python由来 ...
- PC工作原理
提到"技术"这个词时,大多数人都会想到计算机.事实上,我们生活中的方方面面都离不开计算机部件.家里的电器设备有内置的微处理器,例如电视机.甚至汽车里也装有计算机.但是,提到计算机大 ...