TreeSet
是 Java 中的一個有序集合實現(xiàn),它基于紅黑樹數(shù)據(jù)結(jié)構(gòu)來存儲元素,可以保持元素的自然順序(默認情況下升序)或者根據(jù)自定義比較器來進行排序。下面是關(guān)于 TreeSet
的基本介紹、細節(jié)討論、使用注意事項、常用方法以及一些底層實現(xiàn)細節(jié)。
基本介紹:
-
TreeSet
是Set
接口的實現(xiàn)類,它實現(xiàn)了一個有序的、無重復元素的集合。 -
TreeSet
中的元素是按照其自然順序或者比較器的順序進行排序的。 -
TreeSet
不允許存儲重復的元素,每個元素在集合中只能出現(xiàn)一次。
細節(jié)討論:
-
TreeSet
會根據(jù)元素的自然順序或者自定義的比較器來進行排序。如果元素沒有實現(xiàn)Comparable
接口并且沒有提供比較器,會在運行時拋出ClassCastException
。 - 添加、刪除和查找操作的時間復雜度平均為 O(log n),其中 n 是集合的大小。
-
TreeSet
不是線程安全的,如果在多線程環(huán)境下使用,需要進行適當?shù)耐娇刂啤?/li>
使用注意事項:
- 在使用
TreeSet
時,元素需要具有可比較性(可以用instanceOf作為防護機制),要么實現(xiàn)Comparable
接口,要么在構(gòu)造TreeSet
時提供一個比較器。 - 自然順序是指元素的默認順序,如數(shù)字的升序、字符串的字典序等。如果需要不同的順序,可以通過比較器來實現(xiàn)。
常用方法:
-
add(E e)
: 向集合中添加一個元素。 -
remove(Object o)
: 從集合中移除指定的元素。 -
contains(Object o)
: 判斷集合是否包含指定的元素。 -
isEmpty()
: 判斷集合是否為空。 -
size()
: 返回集合中元素的數(shù)量。 -
clear()
: 清空集合中的所有元素。
底層源碼和底層實現(xiàn):
-
TreeSet
的底層基于紅黑樹(Red-Black Tree)數(shù)據(jù)結(jié)構(gòu)來存儲元素。紅黑樹是一種自平衡的二叉查找樹,確保樹的高度始終保持在一個相對較小的范圍內(nèi),從而保證了添加、刪除和查找操作的高效性能。 - 紅黑樹的特性使得元素在樹中按照順序排列,從而實現(xiàn)了
TreeSet
的有序性。 - 通過自平衡的操作,紅黑樹能夠在插入和刪除元素時自動進行樹的重新平衡,從而保持樹的結(jié)構(gòu)穩(wěn)定。
總之,TreeSet
提供了一個有序的集合實現(xiàn),通過底層的紅黑樹數(shù)據(jù)結(jié)構(gòu)實現(xiàn)了高效的元素存儲、添加、刪除和查找操作。在需要保持順序的集合場景下,可以使用 TreeSet
。文章來源:http://www.zghlxwxcb.cn/news/detail-677661.html
TreeSet的底層代碼分析:文章來源地址http://www.zghlxwxcb.cn/news/detail-677661.html
public class TreeSet_ {
public static void main(String[] args) {
//1. 當我們使用無參構(gòu)造器,創(chuàng)建 TreeSet 時,仍然是無序的(存進去的和取出來的順序不一樣),但是取出來的順序是按自然順序排序的(自然順序是指元素的默認順序,如數(shù)字的升序、字符串的字典序等)
//2. 如果需要不同的順序,可以通過比較器來實現(xiàn)。如:希望添加的元素,按照字符串的長度來排序
//3. 使用 TreeSet 提供的一個構(gòu)造器,可以傳入一個比較器(匿名內(nèi)部類)
// 并指定排序規(guī)則
//簡單看看源碼
/*
1. 構(gòu)造器把傳入的比較器對象,賦給了 TreeSet 的底層的 TreeMap 的屬性 this.comparator
public TreeMap(Comparator < ? super K > comparator) {
this.comparator = comparator;
}
2. 在 調(diào)用 treeSet.add("tom"), 在底層會執(zhí)行到
if (cpr != null) {//cpr 就是我們的匿名內(nèi)部類(對象)
do {
parent = t;
//動態(tài)綁定到我們的匿名內(nèi)部類(對象)compare
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else //如果相等,即返回 0,這個 Key 就沒有加入
return t.setValue(value);
} while (t != null);
}
*/
// TreeSet treeSet = new TreeSet();//默認自然排序
TreeSet treeSet = new TreeSet(new Comparator() {//自定義排序
@Override
public int compare(Object o1, Object o2) {
//下面 調(diào)用 String 的 compareTo 方法進行字符串大小比較
//讓加入的元素,按照長度大小排序
//return ((String) o2).compareTo((String) o1);
return ((String) o1).length() - ((String) o2).length();
}
});
//添加數(shù)據(jù). treeSet.add("jack");
treeSet.add("ret");//3
treeSet.add("ret1");
treeSet.add("a");
treeSet.add("abc");//3此時這個加不進去,因為此時是按字符串的長度來排序的,長度和tom相同都為3,但若是在自然排序下是可以插入進去的,因為默認的情況下是比較的兩個字符串是否一樣而不是比較的長度
System.out.println("treeSet=" + treeSet);
}
}
到了這里,關(guān)于Java中TreeSet的基本介紹,細節(jié)討論,使用注意事項,常用方法,底層源碼分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!