JAVA8 TreeMap學習筆記

TreeMap

TreeMap集合是基于紅黑樹(Red-Black tree)的 NavigableMap實現(xiàn)筛璧。該集合最重要的特點就是可排序惹恃,該映射根據(jù)其鍵的自然順序進行排序,或者根據(jù)創(chuàng)建映射時提供的 Comparator 進行排序,具體取決于使用的構(gòu)造方法曲秉。這句話是什么意思呢疲牵?就是說TreeMap可以對添加進來的元素進行排序,可以按照默認的排序方式纲爸,也可以自己指定排序方式

【知識點】

  • TreeMap基于紅黑樹實現(xiàn)無容量限制;
  • TreeMap是非線程安全的负蚊;

類名及類成員變量

public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
// 比較器對象
private final Comparator<? super K> comparator;

// 根節(jié)點
private transient Entry<K,V> root;

// 集合大小
private transient int size = 0;

// 樹結(jié)構(gòu)被修改的次數(shù)
private transient int modCount = 0;

// 靜態(tài)內(nèi)部類用來表示節(jié)點類型
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; // 指向父節(jié)點的引用(指針)
boolean color = BLACK; //
}
}

類構(gòu)造方法

public TreeMap() { // 1,無參構(gòu)造方法
comparator = null; // 默認比較機制
}

public TreeMap(Comparator<? super K> comparator) { // 2家妆,自定義比較器的構(gòu)造方法
this.comparator = comparator;
}

public TreeMap(Map<? extends K, ? extends V> m) { // 3,構(gòu)造已知Map對象為TreeMap
comparator = null; // 默認比較機制
putAll(m);
}

public TreeMap(SortedMap<K, ? extends V> m) { // 4伤极,構(gòu)造已知的SortedMap對象為TreeMap
comparator = m.comparator(); // 使用已知對象的構(gòu)造器
try {
buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
}
  • put(K key, V value)
public V put(K key, V value) {
Entry<K,V> t = root; // 獲取根節(jié)點

// 如果根節(jié)點為空哨坪,則該元素置為根節(jié)點
if (t == null) {
compare(key, key); // type (and possibly null) check

root = new Entry<>(key, value, null);
size = 1; // 集合大小為1
modCount++; // 結(jié)構(gòu)修改次數(shù)自增
return null;
}

int cmp;
Entry<K,V> parent;
Comparator<? super K> cpr = comparator; // 比較器對象

// 如果比較器對象不為空,也就是自定義了比較器
if (cpr != null) {
do { // 循環(huán)比較并確定元素應插入的位置(也就是找到該元素的父節(jié)點)
parent = t; // t就是root

// 調(diào)用比較器對象的compare()方法届慈,該方法返回一個整數(shù)
cmp = cpr.compare(key, t.key);
if (cmp < 0) // 待插入元素的key"小于"當前位置元素的key凌箕,則查詢左子樹
t = t.left;
else if (cmp > 0) // 待插入元素的key"大于"當前位置元素的key,則查詢右子樹
t = t.right;
else // "相等"則替換其value牵舱。
return t.setValue(value);
} while (t != null);
}

// 如果比較器對象為空芜壁,使用默認的比較機制
else {
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key; // 取出比較器對象
do { // 同樣是循環(huán)比較并確定元素應插入的位置(也就是找到該元素的父節(jié)點)
parent = t;
cmp = k.compareTo(t.key); // 同樣調(diào)用比較方法并返回一個整數(shù)
if (cmp < 0) // 待插入元素的key"小于"當前位置元素的key,則查詢左子樹
t = t.left;
else if (cmp > 0) // 待插入元素的key"大于"當前位置元素的key慧妄,則查詢右子樹
t = t.right;
else // "相等"則替換其value塞淹。
return t.setValue(value);
} while (t != null);
}

Entry<K,V> e = new Entry<>(key, value, parent); // 根據(jù)key找到父節(jié)點后新建一個節(jié)點
if (cmp < 0) // 根據(jù)比較的結(jié)果來確定放在左子樹還是右子樹
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++; // 集合大小+1
modCount++; // 集合結(jié)構(gòu)被修改次數(shù)+1
return null;
}

自定義比較器

  1. key為String類型,因為String實現(xiàn)了Comparable接口饱普,所以按照String類中的compareTo方法進行排序;
  2. TreeMap的key實現(xiàn)Comparable接口并實現(xiàn)compareTo方法谁帕;
public class User implements Comparable<User>{
private String username;
private int age;

public User(String username, int age) {
this.username = username;
this.age = age;
}

@Override
public String toString() {
return "User [username=" + username + ", age=" + age + "]";
}
@Override
public int compareTo(User user) {
int temp = this.age - user.age;
return temp == 0 ? this.username.compareTo(user.username) : temp;
}
}
  1. 使用TreeMap的構(gòu)造方法傳遞比較器
Map<User3, String> map = new TreeMap<>(new TreeMapComparator());
  1. 使用匿名內(nèi)部類的形式來寫比較器
Map<User3, String> map = new TreeMap<>(new Comparator<User3>() {

@Override
public int compare(User3 o1, User3 o2) {
int temp = o1.getAge() - o2.getAge();
return temp == 0 ? o1.getUsername().compareTo(o2.getUsername()) : temp;
}
});

參考資料

http://www.reibang.com/p/69f11fc9ea38

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匈挖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舶吗,更是在濱河造成了極大的恐慌贮折,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踊赠,死亡現(xiàn)場離奇詭異每庆,居然都是意外死亡,警方通過查閱死者的電腦和手機缤灵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門腮出,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胚嘲,你說我怎么就攤上這事」ッ蹋” “怎么了妓雾?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長妒蛇。 經(jīng)常有香客問我楷拳,道長,這世上最難降的妖魔是什么唯竹? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任浸颓,我火速辦了婚禮,結(jié)果婚禮上产上,老公的妹妹穿的比我還像新娘晋涣。我一直安慰自己,他們只是感情好谢鹊,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著偎巢,像睡著了一般兼耀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘤运,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音但金,去河邊找鬼似谁。 笑死,一個胖子當著我的面吹牛巩踏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播塞琼,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼彪杉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了攀唯?” 一聲冷哼從身側(cè)響起渴丸,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤另凌,失蹤者是張志新(化名)和其女友劉穎戒幔,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诗茎,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡敢订,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了玉掸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片醒叁。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖啊易,靈堂內(nèi)的尸體忽然破棺而出饮睬,到底是詐尸還是另有隱情,我是刑警寧澤捆愁,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布昼丑,位于F島的核電站,受9級特大地震影響菩帝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呼奢,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一握础、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧禀综,春花似錦他匪、人聲如沸夸研。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姐扮。三九已至衣吠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惊搏,已是汗流浹背忧换。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留酪耳,地道東北人刹缝。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像言疗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子洲守,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容