JDK-In-Action-TreeMap

TreeMap

基于红黑树的NavigableMap实现.元素根据Key的自然顺序排序,或者是根据构造函数传入的Comparator排序.

该集合对containsKey, get, put and remove的操作保证log(n)的时间复杂度.算法实现改编自Cormen, Leiserson, and Rivest的<<算法导论>>(Introduction to Algorithms).

注意为了保证正确实现有序Map,Comparable 和 Comparator 需要与 equals 保持一致性的语义.

当且仅当c.compare(e1, e2)==0具有与e1.equals(e2)相同的布尔值时, 比较器c对一组元素S的排序与equals一致.

实现是非线程安全的,若需要多线程访问,要使用同步包装器或者同步容器.

迭代器方法遵循集合的快速失败语义:迭代器创建之后的任何其他修改将导致ConcurrentModificationException异常.

API Example

元素查找之 Contains

 TreeMap<Integer, Object> treeMap = new TreeMap<>();
 treeMap.put(1, 1);
 treeMap.put(2, 2);

 //log(n)时间复杂度
 assertTrue(treeMap.containsKey(1));

 //线性时间复杂度
 assertTrue(treeMap.containsValue(1));

元素查找之 Get

 TreeMap<Integer, Object> treeMap = new TreeMap<>();
 treeMap.put(1, 1);
 treeMap.put(2, 2);

 //log(n)时间复杂度
 Object value = treeMap.get(2);
 assertEquals(value, 2);

元素查找之最大最小

 TreeMap<Integer, Object> treeMap = new TreeMap<>();
 treeMap.put(1, 1);
 treeMap.put(2, 2);
 treeMap.put(3, 3);

 //log(n)时间复杂度

 //最小值
 assertEquals(treeMap.firstKey(), 1);
 //删除并返回最小值
 Map.Entry<Integer, Object> firstEntry = treeMap.pollFirstEntry();
 assertEquals(firstEntry, "1=1");

 //最大值
 assertEquals(treeMap.lastKey(), 3);
 //删除并返回最大值
 Map.Entry<Integer, Object> lastEntry = treeMap.pollLastEntry();
 assertEquals(lastEntry, "3=3");

元素查找之范围比较


 TreeMap<Integer, Object> treeMap = new TreeMap<>();
 treeMap.put(1, 1);
 treeMap.put(3, 3);
 treeMap.put(5, 5);
 treeMap.put(7, 7);
 treeMap.put(9, 9);

 //集合中小于等于指定key的最大key
 Integer floorKey = treeMap.floorKey(3);
 assertEquals(floorKey, 3);

 //集合中小于等于指定key的最大key对应的映射
 Map.Entry<Integer, Object> floorEntry = treeMap.floorEntry(3);
 assertEquals(floorEntry, "3=3");


 //集合中大于等于指定key的最小key
 Integer ceilingKey = treeMap.ceilingKey(5);
 assertEquals(ceilingKey, 5);

 //集合中大于等于指定key的最小key对应的映射
 Map.Entry<Integer, Object> ceilingEntry = treeMap.ceilingEntry(5);
 assertEquals(ceilingEntry, "5=5");


 //集合中小于指定key的最大key
 Integer lowerKey = treeMap.lowerKey(3);
 assertEquals(lowerKey, 1);

 //集合中小于指定key的最大key的映射
 Map.Entry<Integer, Object> lowerEntry = treeMap.lowerEntry(3);
 assertEquals(lowerEntry, "1=1");

 //集合中大于指定key的最小key
 Integer higherKey = treeMap.higherKey(5);
 assertEquals(higherKey, 7);

 //集合中大于指定key的最小key的映射
 Map.Entry<Integer, Object> higherEntry = treeMap.higherEntry(5);
 assertEquals(higherEntry, "7=7");

元素查找之范围比较视图 Map

 TreeMap<Integer, Object> treeMap = new TreeMap<>();
 treeMap.put(1, 1);
 treeMap.put(3, 3);
 treeMap.put(5, 5);
 treeMap.put(7, 7);
 treeMap.put(9, 9);

 //[,5) 返回treeMap中严格小于toKey的视图map,视图map共享底层数据
 SortedMap<Integer, Object> headMap = treeMap.headMap(5);
 assertEquals(headMap, "{1=1, 3=3}");

 //[5,) 返回treeMap中大于等于fromKey的视图map,视图map共享底层数据
 SortedMap<Integer, Object> fromMap = treeMap.tailMap(5);
 assertEquals(fromMap, "{5=5, 7=7, 9=9}");

 //[2,9) 返回treeMap中大于等于fromKey且小于toKey的视图map,视图map共享底层数据
 SortedMap<Integer, Object> subMap = treeMap.subMap(2, 9);
 assertEquals(subMap, "{3=3, 5=5, 7=7}");

构造函数之指定 Map集合

 Map<Integer, Object> src = new HashMap<>();
 src.put(1, 1);
 src.put(2, 2);

 //构造时间复杂度为n*log(n)
 TreeMap<Integer, Object> treeMap = new TreeMap<>(src);
 assertEquals(treeMap, "{1=1, 2=2}");

构造函数之指定有序 Map集合

 SortedMap<Integer, Object> src = new TreeMap<>();
 src.put(1, 1);
 src.put(2, 2);

 //构造时间复杂度为线性时间,直接使用src的顺序和比较器
 TreeMap<Integer, Object> treeMap = new TreeMap<>(src);
 assertEquals(treeMap, "{1=1, 2=2}");

构造函数之指定比较器

 //整数逆序的比较器
 TreeMap<Integer, Object> treeMap = new TreeMap<>((o1, o2) -> o2 - o1);
 treeMap.put(1, 1);
 treeMap.put(2, 2);
 assertEquals(treeMap, "{2=2, 1=1}");

构造函数之空 Map

 TreeMap<Integer, Object> treeMap = new TreeMap<>();
 assertEquals(treeMap, "{}");

集合元素顺序逆转的视图 Map

 TreeMap<Integer, Object> treeMap = new TreeMap<>();
 treeMap.put(1, 1);
 treeMap.put(3, 3);
 treeMap.put(5, 5);

 assertEquals(treeMap, "{1=1, 3=3, 5=5}");

 NavigableMap<Integer, Object> descendingMap = treeMap.descendingMap();

 assertEquals(descendingMap, "{5=5, 3=3, 1=1}");

 NavigableSet<Integer> descendingKeySet = treeMap.descendingKeySet();

 assertEquals(descendingKeySet, "[5, 3, 1]");
上一篇:java-TreeMap.get()返回Null,即使键存在


下一篇:Java中不是CuncurrentSkipListMap的线程安全方法