Java集合之TreeSet
TreeSet
閱讀這篇文章只需5-10分鐘。
TreeSet是SortedSet介面的實現類,正如SortedSet名字暗示的,TreeSet可以確保集合元素處於排序狀態。與HashSet集合相比,TreeSet還提供瞭如下幾個額外方法:
- Comparator comparator();如果TreeSet採用了定製排序,則該方法返回定製排序所使用Comparator;如果TreeSet採用了自然排序,則返回null;
- Object first();返回集合中的第一個元素;
- Object last();返回集合中的最後一個元素;
- Object lower(Object o);返回集合中位於指定元素之前的元素(即小於指定元素的最大元素,參考元素不需要是TreeSet集合裡的元素);
- Object higher(Object o);返回集合中位於指定元素之後的元素(即大於指定元素的最小元素,參考元素不需要是TreeSet集合裡的元素);
- SortedSet subSet(Object fromElement,Object toElement);返回此Set的子集合,返回從fromElement,Object (包含到)toElement(不包含);
- SortedSet headSet(Object toElement);返回此Set的子集,由小於toElement的元素組成;
- SortedSet tailSet(Object fromElement);返回此Set的子集,由大於或等於fromElement的元素組成;
示例:
package com.collection;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet set = new TreeSet();
set.add(9);
set.add(-2);
set.add(3);
set.add(10);
System.out.println(set);//[-2, 5, 9, 10]
//輸出集合中第一個元素
System.out.println("set.first() = "+set.first());//set.first() = -2
//輸出集合中最後一個元素
System.out.println("set.last() = "+set.last());//set.last() = 10
//返回小於4的子集,不包含4
System.out.println("set.headSet() = "+set.headSet(4));//set.headSet() = [-2, 3]
//返回大於5的子集,包含5
System.out.println("set.tailSet() = "+set.tailSet(5));//set.tailSet() = [9, 10]
//返回大於等於-3,小於4的子集
System.out.println("set.subSet() = "+set.subSet(-3, 4));//set.subSet() = [-2, 3]
}
}
與HashSet集合採用通過hash演算法來決定元素的儲存位置不同,TreeSet採用紅黑樹的資料結構來儲存集合元素。
TreeSet支援兩隻排序方法:自然排序與定製排序。
自然排序:
TreeSet會呼叫集合元素的compareTo(Object o)方法來比較元素之間的大小關係,然後將集合元素按升序排列,這種方式是自然排序。
Java提供了一個Comparable介面,該介面定義一個compareTo(Object o)方法,該方法返回一個整數值,實現該介面的類必須實現該方法,實現該介面的類的物件就可以比較大小。當一個物件呼叫該方法與另一個物件進行比較時,例如:obj1.compareTo(obj2),如果該方法返回0,則代表這兩個物件相等;如果該方法返回一個正整數,則表明obj1大於obj2;如果該方法返回一個負整數,則表明obj1小於obj2。
特別篇:
Java的一些常用類已經實現了Comparable介面,並提供了比較大小的標準。下面是視線了Comparable介面的常用類。
1 BigDecimal、BigInterger以及所有的數值型對應的包裝類:按它們對應的數值大小進行比較。
2 Character: 按字元的UNICODE值進行比較。
3 Boolean: true對應的包裝示例大於false對應的包裝類例項。
4 String: 按字串中字元的UNICODE值進行比較。
5 Date、Time: 後面的時間、日期比前面的時間、日期大。
問題1:
如果試圖把一個物件新增到TreeSet時,則該物件的類必須實現Comparable介面,否則程式會丟擲異常java.lang.ClassCastException。
如下:
public static void main(String[] args) {
TreeSet t1= new TreeSet();
t1.add(new Err());
t1.add(new Err());
//Exception in thread "main" java.lang.ClassCastException:
}
class Err{
}
原因:
TreeSet集合中新增兩個Err物件,新增第一個物件時,TreeSet裡沒有任何元素,所以不會出現任何問題;當新增第二個Err物件時,TreeSet就會呼叫該物件的compareTo(Object obj)方法與集合中的其他元素進行比較—如果其對應的類沒有實現Comparable 介面,則會引發ClassCastException異常。
問題2:
在實現compareTo(Object o)方法時,都需要將被比較物件obj強制型別轉換成相同型別,因為只有相同類的兩個示例才會比較大小。
當試圖把一個大物件新增到TreeSet集合時,TreeSet會呼叫該物件的compareTo(Object o)方法與集合中的其他元素進行比較—這就要求集合中的其他元素與該元素是同一類的示例,否則丟擲ClassCaseException異常。
總之一句話,如果希望TreeSet能夠正常執行,TreeSet只能新增同一型別物件。
錯誤示例:
public static void main(String[] args) {
TreeSet t2 = new TreeSet();
t2.add("hello");
t2.add(1);
//java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
}
TreeSet判斷標準:
TreeSet判斷兩個物件是否相等的唯一標準是:兩個物件通過compareTo(Object o)方法比較是否返回0 —如果通過compareTo(Object o)方法比較返回0,TreeSet則會認為它們相等:否則就認為它們不相等。
示例:
我們定義一個類z ,實現compareTo(Object o )方法,重寫equals()方法,TreeSet判斷兩個物件的標準上面已經講了,它會已兩個物件的compareTo(Object o )比較的返回值來判斷,為0時,代表兩個物件相等;為1時,代表obg1大於obj2對像,否則返回-1。
class z implements Comparable{
int size;
public z( int size){
this.size = size;
}
public int compareTo(Object o) {
//永遠不相等
return 1;
}
public boolean equals(Object obj) {
return true;
}
}
public static void main(String[] args) {
TreeSet t3 = new TreeSet();
z z1 = new z(6);
t3.add(z1);
t3.add(z1);
//TreeSet添加了兩個z物件到集合中,並且新增成功了
System.out.println(t3);
//輸出的結果顯示,這兩個物件實際是相等的,之所以能新增成功的原因是compareTo 返回了1,這就表示按當前的示例
無論新增物件z物件到TreeSet集合中,都會成功,因為它們始終不相等(也就是compareTo返回值 為 0)
//[[email protected], [email protected]]
}
正確示例:
判斷兩個物件的是否相等的參照標準,下面我們已Size為例;
class z implements Comparable{
int size;//判斷標準
public z( int size){
this.size = size;
}
public int compareTo(Object o) {
z z1 = (z)o;//型別轉換
return this.size > z1.size ? 1 :this.size < z1.size ? -1 : 0;
}
public boolean equals(Object obj) {
if(this == obj)
{
return true;
}
if(obj != null && obj.getClass() == z.class)
{
z z1 = (z)obj) ;//型別轉換
return z1.size == this.size;
}
return false;
}
}
public static void main(String[] args) {
TreeSet t5 = new TreeSet();
t5.add(new R1(6));
t5.add(new R1(6));
t5.add(new R1(-6));
t5.add(new R1(1));
System.out.println(t5);
//對重複的元素6進行了對比,輸出結果顯示只有,6、-6、1
//[[email protected], [email protected], [email protected]]
}
注意:
與HashSet類似的是,如果TreeSet中包含了可變物件,當可變物件的示例變數被修改時,TreeSet在處理這些物件時將非常複雜,而且容易出錯。為了讓程式更加健壯,推薦不要修改放入HashSet和TreeSet集合中元素的關鍵例項變數。
定製排序
TessSet 的自然排序是根據集合元素的大小,TreeSet將它們以升序排列。如果需要實現定製排序,例如以降序排列,則可通過Comparator介面的幫助。該接口裡包含一個int compate(T o1,T o2)方法,該方法用於比較o1和o2的大小:如果該方法返回正整數,則表明o1大於o2;如果該方法返回0,則表明o1等於o2;如果該方法返回負整數,則表明o1小於o2。
示例:
class R2 implements Comparable{
int size;//判斷標準
public R2( int size){
this.size = size;
}
public int compareTo(Object o) {
R2 r = (R2)o;//型別轉換
return this.size > r.size ? -1 :this.size < r.size ? 1 : 0;
}
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj != null && obj.getClass() == z.class){
R2 r = (R2)obj;//型別轉換
return r.size == this.size;
}
return false;
}
}
public static void main(String[] args) {
TreeSet t6 = new TreeSet();
t6.add(new R2(6));
t6.add(new R2(6));
t6.add(new R2(-6));
t6.add(new R2(1));
System.out.println(t6);
R2 r1 = (R2) t6.first();
System.out.println("r1.first() = "+r1.size);//set.first() = 6
//輸出集合中最後一個元素
R2 r2 = (R2) t6.last();
System.out.println("r2.last() = "+r2.size);//set.last() = -6
}
Things won are done; joy’s soul lies in the doing.
得到即是完結,快樂的精髓在於過程。
相關推薦
java 集合之TreeSet的用法
Java中 TreeMap和TreeSet算是java集合類裡面比較有難度的資料結構。和普通的HashMap不一樣,普通的HashMap元素存取的時間複雜度一般是O(1)的範圍,而TreeMap
java 集合之TreeSet詳解
首先說明一下,之前看了一下文章提出TreeSet在新增第一個元素的時候是不比較大小的,這種說發是錯誤的,在第一次新增的時候比較的是第一個物件本省返回的引數是0,下面我們用程式驗證一下:首先由一個Student的內部類:裡面有兩個引數,年齡和名稱我們後期自定義排序也是用得到的。
Java集合之TreeSet
TreeSet 閱讀這篇文章只需5-10分鐘。 TreeSet是SortedSet介面的實現類,正如SortedSet名字暗示的,TreeSet可以確保集合元素處於排序狀態。與HashSet集合相比,TreeSet還提供瞭如下幾個額外方法: Compar
死磕 java集合之TreeSet源碼分析
.com 海洋 clu 的區別 寫入 stk 真的 strac pro 問題 (1)TreeSet真的是使用TreeMap來存儲元素的嗎? (2)TreeSet是有序的嗎? (3)TreeSet和LinkedHashSet有何不同? 簡介 TreeSet底層是采用TreeM
Java集合之HashSet、LinkedHashSet、TreeSet
討論集合關注的問題: 底層資料結構 增刪改查方式 初始容量,擴容方式,擴容時機 執行緒安全與否 是否允許空,是否允許重複,是否有序 1. 概述 前篇,我寫了關於Map系列的集合(點選跳轉);本篇重新回顧Coll
Java集合之四Set、HashSet、LinkedHashSet、TreeSet
Set Set介面是Collection的子介面,set介面沒有提供額外的方法。 Set 集合不允許包含相同的元素,最多允許一個null值,如果試把兩個相同的元素加入同一個 Set 集合中,則新增操作失敗。 Set 判斷兩個物件是否相同不是使用 == 運算子,而是根據 eq
Java集合之Collection與之子類回顧
asn void 排序 dha 避免 bst 自然 我們 tip Java學習這麽久,打算這幾天回顧下java的基本知識點,首先是集合。 一、常用集合類關系圖 Collection |___List 有序,可重復 |___ArrayList 底層數據結構是
java集合之ArrayList源碼解讀
object類 util tcap div new length ext ali xtend 源自:jdk1.8.0_121 ArrayList繼承自AbstractList,實現了List、RandomAccess、Cloneable、Serializable。 變量
java集合之列表:ArrayList、Vector、LinkedList
sta pop arraylist 允許 dex nsa pack java jdk 1 package com.jdk7.chapter4; 2 3 import java.util.ArrayList; 4 import java.util.Link
java集合之collection
相等 支持 隨機 microsoft index 實現 collect 基於 ffffff Collection架構層次關系1.Set (不能有重復元素)1.1HashSet1.1.1LinkedHashSet2.List (必須保持元素特定的順序)2.1Arr
java集合之set
ash 字符數組 his err new rgs return 清除 single 1 public class Demo1_Set { 2 3 /* 4 * set集合無序、不可重復、無索引 5 */ 6 p
java集合之Map
map 增強for循環 keyset map.entry ear 覆蓋 integer pre 形式 1. Map集合之基礎增刪查等功能 1 public class Demo1_Map { 2 3 /* 4 * Map集合是以鍵值對的形式
Java集合之List常見操作
collect 定位 lastindex 索引 hot move 值對象 安排 ast 一.定義集合(Collection)是Java存儲對象常見的一種方式;集合中的各個對象最終存儲在類似數組[]中。那麽,為什麽有了數組還要用集合呢?因為,集合中的長度可變,所以不用一開始就
Java集合之LinkedList常見實例操作,實例說明
remove ati 使用 util 概念 dex bool 新增 obj 一.LinkedList常見操作 package List相關; /** * LinkedList 鏈接列表 * LinkedList:底層使用的鏈表數據結構。特點:增刪速度快,查詢速度稍慢;
Java 集合之Set簡介
返回值 接口模擬 區別 key mov 無序 刪除 tor 可能 一.Set集合Set:不包含重復元素的集合。 更正式地,集合不包含一對元素e1和e2 ,使得e1.equals(e2) ,並且最多一個空元素。正如其名稱所暗示的那樣,這個接口模擬了數學集抽象。一些集合實現對它
Java 集合之HashSet常用方法實例介紹
java args arr 子類 boolean 常用 地址 比例 可能 一.簡介HashSet是Set常見的子類對象,此類實現Set接口,由哈希表(實際為HashMap實例)支持。 對集合的叠代次序不作任何保證; 特別是,它不能保證訂單在一段時間內保持不變。這個類允許nu
java集合之ArrayList鏈表基礎
print ins 定位 move ensure cte ini for循環 獲取 ArrayList可變數組 : arrayList繼承AbstractList抽象類,實現list接口,底層基於數組實現。可存放null,除了非同步的之外,大致等同Vector。適用快速訪問
java集合之Vector向量基礎
end 元素 incr pri 設置 == protected ava 動態 Vector向量: vector類似動態數組,向量和數組類似,但是數組容量一旦確定不可更改,而向量的容量可變。向量只可以保存任何類型對象且容量不限制,數組對元素類型無限制但是容量有限。 適用場合:
Java 集合之 Collection
face exception ima oci 實體 try ransient seq 對象的引用 集合就是一組數的集合,就像是一個容器,但是我們應該清楚的是集合中存放的都是對象的引用,而不是真正的實體。而我們常說的集合中的對象其實指的就是對象的引用。 我們可以把集合理解
Java 集合之 Map(轉載)
iter 估算 做的 sortedmap 的區別 復雜度 detail 四種 測試環境 原文鏈接 :http://www.importnew.com/20386.html Map 就是另一個頂級接口了,總感覺 Map 是 Collection 的子接口呢。Map 主