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 ...
随机推荐
- 微信支付开发(1) JS API支付
关键字:微信支付 微信支付v3 jsapi支付 统一支付 Native支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3 ...
- select,poll,epoll比较
除常用文件i/o外,其他常用io模型:io多路复用(select和poll系统调用)信号驱动I/Olinux专有的epoll编程接口异步io(aio),linux在glibc中提供有基于线程的 pos ...
- 【jQuery api】isArray
<!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-l ...
- 即使用ADO.NET,也要轻量级实体映射,比Dapper和Ormlite均快
不管出于什么原因,有时候框架人员摒弃了NH或EF,而使用原生数据库访问对象. 为了优美的编程,用上我写的轻量级映射扩展方法吧 目的:将SqlDataReader自动转换成T类型 代码如下: /// & ...
- caffe中accuracy和loss用python从log日志里面获取
import re import pylab as pl import numpy as np if __name__=="__main__": accuracys=[] loss ...
- VS2010 MFC对Excel的操作
这是帮别人做项目遇到的一个问题,的那个是纠结了老长时间,本以为是一件很轻松的事... 首先,这里采用了OLE来对Excel进行操作,网上其实有大把的例子,虽然都可以运行,但是并不能满足项目要求,其实我 ...
- Sikuli图形脚本测试工具安装及介绍(适合小白的测试神器)
sikuli简单安装以及介绍附图: 一.简单介绍 SikuliX官方网站:https://launchpad.net/sikuli/(官方的最新版本是SikuliX1.1.0更新于2015-10-06 ...
- Java面试之SpringMVC总结以及在面试中的一些问题.
1.简单的谈一下SpringMVC的工作流程? 流程 1.用户发送请求至前端控制器DispatcherServlet 2.DispatcherServlet收到请求调用HandlerMapping处理 ...
- C#操作剪贴板
操作剪贴版,主要用到了ClipBoard类. 该类位于 System.Windows(WPF)或System.Windows.Forms(Winform)下. 1.设置内容到剪贴版上: 主要用到Cli ...
- 09 Object
Object 在看 ES6 Object的时候,我发觉ES5 Object 的更新我并不是完全知道. 于是觉得还是看一下. 1. __proto__ 作为一个 半吊子前端开发人员. 居然不知道这个.. ...