浅析Java集合类源码(三)--- TreeSet, TreeMap 及 常见集合类的比较
2016-09-18 12:05
363 查看
6.TreeSet
TreeSet继承AbstractSet,实现NavigableSet,Cloneable,Serializable接口,TreeSet不是线程安全类。public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable
和HashSet类似,TreeSet使用TreeMap的数据结构来保存元素。键Key是需要保存的元素,值Value是一个静态对象PRESENT
private static final Object PRESENT = new Object();
(1)初始化
由于TreeSet使用TreeMap对其元素进行保存,因此调用TreeMap的初始化方法private transient NavigableMap<E,Object> m;
public TreeSet() { this(new TreeMap<E,Object>()); }
TreeSet(NavigableMap<E,Object> m) { this.m = m; }
(2)添加
TreeSet调用TreeMap的put()方法来添加元素public boolean add(E e) { return m.put(e, PRESENT)==null; }
(3)删除
TreeSet调用TreeMap的remove()方法来移除元素public boolean remove(Object o) { return m.remove(o)==PRESENT; }
7.TreeMap
TreeMap继承AbstractMap,实现NavigableMap,Cloneable,Serializable接口。TreeMap不是线程安全类。public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable
TreeMap使用Entry数据结构保存键Key和值Value。并使用数据结构红黑树(Red-Black Tree)结构保存节点Entry。
static final class Entry<K,V> implements Map.Entry<K,V> { K key; V value; Entry<K,V> left; Entry<K,V> right; Entry<K,V> parent; boolean color = BLACK; }
因为TreeMap使用红黑树的数据结构对Entry进行保存,这就要Entry的key是可以比较的。因此,键key的类必须实现Comparable接口或Comparator接口。
(1)查找
通过get(Object key)方法来查找元素,会调用getEntry(Object key)方法来查找元素。public V get(Object key) { Entry<K,V> p = getEntry(key); return (p==null ? null : p.value); }
getEntry先判断Key是否实现Comparator接口,若实现,则调用getEntryUsingComparator方法,否则使用Comparable的compareTo方法进行Key的比较。两种方法的比较都差不多,当Key比节点小,往左走;当Key比节点大,往右走;相等则返回。
Comparable<? super K> k = (Comparable<? super K>) key; Entry<K,V> p = root; while (p != null) { int cmp = k.compareTo(p.key); if (cmp < 0) p = p.left; else if (cmp > 0) p = p.right; else return p; } return null;
(2)添加
添加和查找一样,先判断Key是否实现Comparator接口,若实现,使用compare()方法进行比较。parent = t; cmp = cpr.compare(key, t.key);
否则,使用Comparable的compareTo方法进行比较。
parent = t; cmp = k.compareTo(t.key);
若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);
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
接下来调用fixAfterInsertion方法,按照CLR的Introduction to Algorithms的红黑树结构进行调整。
(3)删除
remove方法先调用查找的getEntry方法查找到需要删除的节点,然后调用deleteEntry方法删除该节点public V remove(Object key) { Entry<K,V> p = getEntry(key); if (p == null) return null; V oldValue = p.value; deleteEntry(p); return oldValue; }
deleteEntry方法先调用successor方法找到被删除节点p的后继节点s,然后将的key和value都设为s节点的key和value,再将s节点赋值给p节点,然后调整p节点
Entry<K,V> s = successor(p); p.key = s.key; p.value = s.value; p = s;
接下来调用fixAfterDeletion方法,按照CLR的Introduction to Algorithms的红黑树结构进行调整。
常见集合类的比较:
Vector和ArrayList的比较
(1)相同点:
Vector和ArrayList均是采用数组结构保存元素(2)不同点:
Vector在增长时增长为原数组的2倍;ArrayList在增长时增长为原数组的1.5倍;Vector是线程安全类;ArrayList不是线程安全类
HashMap和Hashtable的比较
(1)相同点:
采用索引数组+链表的方式对元素进行存储(2)不同点:
Hashtable扩展时增长为(当前数组*2+1);HashMap扩展时增长为(当前数组*2);插入元素时,Hashtable插入至链表的头部;HashMap插入至链表的尾部
Hashtable的hash值计算:(元素hash值 % 当前数组容量);HashMap的hash值计算:(元素hash值 & (当前数组容量 -1))
Hashtable是线程安全类;HashMap不是线程安全类
HashMap和TreeMap的比较
(1)相同点:
都不是线程安全类(2)不同点:
HashMap是根据key的hash值来计算key在Hash表中的位置,因此Key的类型应该重写hashCode方法,并且应该重写equals方法,以便对key本身是否相同进行比较;TreeMap是根据key本身的大小进行比较,因此应该实现Comparator接口并重写compare方法,或实现Comparable接口并重写compareTo方法HashMap采用数组+链表的方式进行存储,因此会在元素增多时扩展数组的长度;TreeMap直接采用红黑树进行存储,因此在插入或删除元素时要对红黑树的结构进行调整
相关文章推荐
- 字符串和字符的比较方法浅析测试(源码摘自microsoft help)
- java集合类TreeMap和TreeSet
- 浅析Java集合类源码(二)--- HashSet, HashMap, Hashtable
- Java源码集合类TreeMap学习1——数据结构3二叉树创建代码
- Java源码集合类TreeMap学习1——数据结构2
- Java集合类4—HashSet、TreeSet、HashMap、TreeMap介绍
- Java源码集合类TreeMap学习1——数据结构5红黑树
- Java集合类HashSet、TreeSet比较
- TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
- Java源码集合类TreeMap学习1——数据结构4平衡二叉树插入一个元素的递归算法
- java集合类TreeMap和TreeSet
- 辛星浅析utf8中比较常见的utf8校对集
- java集合类TreeMap和TreeSet
- 浅析Java集合类源码(一)--- Vector, ArrayList, LinkedList
- Java 集合类 TreeSet、TreeMap
- 字符串和字符比较浅析测试(源码摘自microsoft help)
- java中的几种泛型类——HashSet、HashMap、TreeSet、TreeMap,遍历map,排序,HashTable比较
- java集合类TreeMap和TreeSet
- java 中HashMap、HashSet、TreeMap、TreeSet判断元素相同的几种方法比较
- Java源码集合类TreeMap学习1——数据结构4平衡二叉树创建代码