TreeMap
集合
基本介绍:
当我们使用无参构造器,创建TreeMap
时,仍然是无序的
当我们需要按照某种方式进行排序时,需要使用TreeMap
提供的一个构造器,可以传入一个比较器【匿名内部类】并指定排序规则
继承关系和构造器
构造器:
Constructor and Description |
---|
TreeMap() 使用其键的自然排序构造一个新的空树状图。 |
TreeMap(Comparator<? super K> comparator) 构造一个新的,空的树图,按照给定的比较器排序。 |
TreeMap(Map<? extends K,? extends V> m) 构造一个新的树状图,其中包含与给定地图相同的映射,根据其键的 自然顺序进行排序 。 |
TreeMap(SortedMap<K,? extends V> m) 构造一个包含相同映射并使用与指定排序映射相同顺序的新树映射。 |
方法摘要
Modifier and Type | Method and Description |
---|---|
Map.Entry<K,V> | ceilingEntry(K key) 返回与大于或等于给定键的最小键相关联的键值映射,如果没有此键,则 null 。 |
K | ceilingKey(K key) 返回大于或等于给定键的 null 键,如果没有此键,则返回 null 。 |
void | clear() 从这张地图中删除所有的映射。 |
Object | clone() 返回此 TreeMap 实例的浅拷贝。 |
Comparator<? super K> | comparator() 返回用于订购此地图中的键的比较器,或null 如果此地图使用其键的natural ordering 。 |
boolean | containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。 |
boolean | containsValue(Object value) 如果此地图将一个或多个键映射到指定值,则返回 true 。 |
NavigableSet<K> | descendingKeySet() 返回此地图中包含的键的相反顺序NavigableSet 。 |
NavigableMap<K,V> | descendingMap() 返回此映射中包含的映射的反向排序视图。 |
Set<Map.Entry<K,V>> | entrySet() 返回此地图中包含的映射的Set 视图。 |
Map.Entry<K,V> | firstEntry() 返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null 。 |
K | firstKey() 返回此地图中当前的第一个(最低)键。 |
Map.Entry<K,V> | floorEntry(K key) 返回与小于或等于给定键的最大键相关联的键值映射,如果没有此键,则 null 。 |
K | floorKey(K key) 返回小于或等于给定键的最大键,如果没有这样的键,则返回 null 。 |
void | forEach(BiConsumer<? super K,? super V> action) 对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。 |
V | get(Object key) 返回到指定键所映射的值,或 null 如果此映射包含该键的映射。 |
SortedMap<K,V> | headMap(K toKey) 返回此地图部分的视图,其密钥严格小于 toKey 。 |
NavigableMap<K,V> | headMap(K toKey, boolean inclusive) 返回此地图部分的视图,其键值小于(或等于,如果 inclusive 为真) toKey 。 |
Map.Entry<K,V> | higherEntry(K key) 返回与最小密钥相关联的密钥值映射严格大于给定密钥,如果没有这样的密钥则 null 。 |
K | higherKey(K key) 返回严格大于给定键的最小键,如果没有这样的键,则返回 null 。 |
Set<K> | keySet() 返回此地图中包含的键的Set 视图。 |
Map.Entry<K,V> | lastEntry() 返回与该地图中最大关键字关联的键值映射,如果地图为空,则返回 null 。 |
K | lastKey() 返回当前在此地图中的最后(最高)键。 |
Map.Entry<K,V> | lowerEntry(K key) 返回与最大密钥相关联的密钥值映射严格小于给定密钥,如果没有这样的密钥,则 null 。 |
K | lowerKey(K key) 返回严格小于给定键的最大键,如果没有这样的键,则返回 null 。 |
NavigableSet<K> | navigableKeySet() 返回此地图中包含的键的NavigableSet 视图。 |
Map.Entry<K,V> | pollFirstEntry() 删除并返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null 。 |
Map.Entry<K,V> | pollLastEntry() 删除并返回与该地图中最大密钥相关联的键值映射,如果地图为空,则返回 null 。 |
V | put(K key, V value) 将指定的值与此映射中的指定键相关联。 |
void | putAll(Map<? extends K,? extends V> map) 将指定地图的所有映射复制到此地图。 |
V | remove(Object key) 从此TreeMap 中删除此键的映射(如果存在)。 |
V | replace(K key, V value) 只有当目标映射到某个值时,才能替换指定键的条目。 |
boolean | replace(K key, V oldValue, V newValue) 仅当当前映射到指定的值时,才能替换指定键的条目。 |
void | replaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。 |
int | size() 返回此地图中键值映射的数量。 |
NavigableMap<K,V> | subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) 返回此地图部分的视图,其关键范围为 fromKey 至 toKey 。 |
SortedMap<K,V> | subMap(K fromKey, K toKey) 返回此地图部分的视图,其关键字范围从 fromKey (含)到 toKey ,独占。 |
SortedMap<K,V> | tailMap(K fromKey) 返回此地图部分的视图,其键大于等于 fromKey 。 |
NavigableMap<K,V> | tailMap(K fromKey, boolean inclusive) 返回此地图部分的视图,其键大于(或等于,如果 inclusive 为真) fromKey 。 |
Collection<V> | values() 返回此地图中包含的值的Collection 视图。 |
TreeMap
源码剖析
package collection_.collectionP.map_;
import java.util.Comparator;
import java.util.TreeMap;
/**
* @author: 海康
* @version: 1.0
*/
public class TreeMap_ {
public static void main(String[] args) {
// 在使用无参构造器时,排序是无序的
// 使用无参构造器返回值:{jack=杰克, kristina=克瑞斯提诺, smith=斯密斯, tom=汤姆}
TreeMap treeMap = new TreeMap();
// TreeMap treeMap = new TreeMap(new Comparator() {
// @Override
// public int compare(Object o1, Object o2) {
// // 按照传入的 key 的大小进行排序
// String str1 = (String) o1;
// String str2 = (String) o2;
// return str1.compareTo(str2);
// // 按照key 的长度比较
return str1.length() - str2.length();
// }
// });
treeMap.put("jack","杰克");
treeMap.put("tom","汤姆");
treeMap.put("kristina","克瑞斯提诺");
treeMap.put("smith","斯密斯");
System.out.println(treeMap);
/**
* 源码:
* 第一步:使用TreeMap的构造器,在构造器传入 比较器对象的引用
* public TreeMap(Comparator<? super K> comparator) {
* this.comparator = comparator;完成 comparator属性的初始化
* }
*
* 第二步:执行 put 方法
*
* public V put(K key, V value) {
* 由于第一次添加所以 root的值为 null: private transient Entry<K,V> root;
* Entry<K,V> t = root;
* if (t == null) {所以第一次添加时会执行这里的代码
* 下面调用compare方法是防止传入 null,可以传入null会抛出空指针异常
* compare(key, key); // type (and possibly null) check
*
* root = new Entry<>(key, value, null); new一个Entry完成对象属性初始化
* size = 1; 容量加1
* modCount++; 修改次数加1
* return null;
* }
* int cmp;
* Entry<K,V> parent;
* // split comparator and comparable paths
* Comparator<? super K> cpr = comparator; 将比较器赋给 cpr: private final Comparator<? super K> comparator;
* if (cpr != null) { 如果比较不为null 执行这里代码
* do {
* parent = t;
* cmp = cpr.compare(key, t.key); 动态绑定的执行匿名内部中的 compare方法
* if (cmp < 0)
* t = t.left;
* else if (cmp > 0)
* t = t.right;
* else
* return t.setValue(value); 如果当比较器返回的值相等时,则将原来的value值替换成传入的value值
* } while (t != null);
* }
* else { 如果比较为null 执行这里代码
* if (key == null)
* throw new NullPointerException();
* @SuppressWarnings("unchecked")
* Comparable<? super K> k = (Comparable<? super K>) 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(e);
* size++;
* modCount++;
* return null;
* }
*/
}
}
package com.hspedu.map_;
import java.util.Comparator;
import java.util.TreeMap;
@SuppressWarnings({"all"})
public class TreeMap_ {
public static void main(String[] args) {
//使用默认的构造器,创建TreeMap, 是无序的(也没有排序)
/*
老韩要求:按照传入的 k(String) 的大小进行排序
*/
// TreeMap treeMap = new TreeMap();
TreeMap treeMap = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//按照传入的 k(String) 的大小进行排序
//按照K(String) 的长度大小排序
//return ((String) o2).compareTo((String) o1);
return ((String) o2).length() - ((String) o1).length();
}
});
treeMap.put("jack", "杰克");
treeMap.put("tom", "汤姆");
treeMap.put("kristina", "克瑞斯提诺");
treeMap.put("smith", "斯密斯");
System.out.println("treemap=" + treeMap);
/*
解读源码:
1. 构造器. 把传入的实现了 Comparator接口的匿名内部类(对象),传给给TreeMap的comparator
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
2. 调用put方法
2.1 第一次添加, 把k-v 封装到 Entry对象,放入root
Entry<K,V> t = root;
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
2.2 以后添加
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do { //遍历所有的key , 给当前key找到适当位置
parent = t;
cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的compare
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else //如果遍历过程中,发现准备添加Key 和当前已有的Key 相等,就不添加
return t.setValue(value);
} while (t != null);
}
*/
}
}