1. 程式人生 > >Java集合之TreeSet

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 主