日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Java Set接口详细讲解 TreeSet的定制排序和自然排序

發(fā)布時間:2025/3/15 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java Set接口详细讲解 TreeSet的定制排序和自然排序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Set接口概述

  • Set接口是Collection的子接口,set接口沒有提供額外的方法
  • Set 集合不允許包含相同的元素,如果試把兩個相同的元素加入同一個Set 集合中,則添加操作失敗。
  • Set 判斷兩個對象是否相同不是使用 == 運算符,而是根據(jù) equals() 方法
  • Set實現(xiàn)類之一:HashSet

    1 HashSet 是 Set 接口的典型實現(xiàn),大多數(shù)時候使用 Set 集合時都使用這個實現(xiàn)類。
    2 HashSet 按 Hash 算法來存儲集合中的元素,因此具有很好的存取、查找、刪除性能。

    HashSet 具有以下特點:

    不能保證元素的排列順序
    HashSet 不是線程安全的
    集合元素可以是 null

    HashSet 集合判斷兩個元素相等的標(biāo)準(zhǔn):兩個對象通過 hashCode() 方法比較相等,并且兩個對象的 equals() 方法返回值也相等。
    對于存放在Set容器中的對象,對應(yīng)的類一定要重寫equals()和hashCode(Object obj)方法,以實現(xiàn)對象相等規(guī)則。即:“相等的對象必須具有相等的散列碼”。

    Set實現(xiàn)類之一:HashSet

    向HashSet中添加元素的過程:

    1 當(dāng)向 HashSet 集合中存入一個元素時,HashSet 會調(diào)用該對象的 hashCode() 方法
    來得到該對象的 hashCode 值,然后根據(jù) hashCode 值,通過某種散列函數(shù)決定該對象在 HashSet 底層數(shù)組中的存儲位置。(這個散列函數(shù)會與底層數(shù)組的長度相計算得到在數(shù)組中的下標(biāo),并且這種散列函數(shù)計算還盡可能保證能均勻存儲元素,越是散列分布,該散列函數(shù)設(shè)計的越好)
    2 如果兩個元素的hashCode()值相等,會再繼續(xù)調(diào)用equals方法,如果equals方法結(jié)果為true,添加失敗;如果為false,那么會保存該元素,但是該數(shù)組的位置已經(jīng)有元素了,那么會通過鏈表的方式繼續(xù)鏈接。
    如果兩個元素的 equals() 方法返回 true,但它們的 hashCode() 返回值不相等,hashSet 將會把它們存儲在不同的位置,但依然可以添加成功。

    重寫 hashCode() 方法的基本原則

    • 在程序運行時,同一個對象多次調(diào)用 hashCode() 方法應(yīng)該返回相同的值。
    • 當(dāng)兩個對象的 equals() 方法比較返回 true 時,這兩個對象的 hashCode() 方法的返回值也應(yīng)相等。
    • 對象中用作 equals() 方法比較的 Field,都應(yīng)該用來計算 hashCode 值。

    重寫 equals() 方法的基本原則

    以自定義的Customer類為例,何時需要重寫equals()? ? 當(dāng)一個類有自己特有的“邏輯相等”概念,當(dāng)改寫equals()的時候,總是
    要改寫hashCode(),根據(jù)一個類的equals方法(改寫后),兩個截然不同的實例有可能在邏輯上是相等的,但是,根據(jù)Object.hashCode()方法,它們僅僅是兩個對象。因此,違反了“相等的對象必須具有相等的散列碼”
    結(jié)論:復(fù)寫equals方法的時候一般都需要同時復(fù)寫hashCode方法。通常參與計算hashCode的對象的屬性也應(yīng)該參與到equals()中進(jìn)行計算。

    Set實現(xiàn)類之二:LinkedHashSet

    • LinkedHashSet 是 HashSet 的子類
    • LinkedHashSet 根據(jù)元素的 hashCode 值來決定元素的存儲位置,但它同時使用雙向鏈表維護(hù)元素的次序,這使得元素看起來是以插入順序保存的。
    • LinkedHashSet插入性能略低于 HashSet,但在迭代訪問 Set 里的全部元素時有很好的性能。
    • LinkedHashSet 不允許集合元素重復(fù)。

    Set實現(xiàn)類之三:TreeSet

    • TreeSet 是 SortedSet 接口的實現(xiàn)類,TreeSet 可以確保集合元素處于排序狀態(tài)。
    • TreeSet底層使用樹結(jié)構(gòu)存儲數(shù)據(jù)
    • 新增的方法如下: (了解)
      1 Comparator comparator()
      2 Object first()
      3 Object last()
      4 Object lower(Object e)
      5 Object higher(Object e)
      6 SortedSet subSet(fromElement, toElement) 7SortedSet headSet(toElement)
      8SortedSettailSet(fromElement)
      TreeSet 兩種排序方法:自然排序和定制排序。默認(rèn)情況下,TreeSet 采用自然排序

    排 序—自然排序

    自然排序:TreeSet 會調(diào)用集合元素的 compareTo(Object obj) 方法來比較元素之間的大小關(guān)系,然后將集合元素按升序(默認(rèn)情況)排列
    如果試圖把一個對象添加到 TreeSet 時,則該對象的類必須實現(xiàn) Comparable 接口
    實現(xiàn) Comparable 的類必須實現(xiàn) compareTo(Object obj) 方法,兩個對象即通過compareTo(Object obj) 方法的返回值來比較大小。
    向 TreeSet 中添加元素時,只有第一個元素?zé)o須比較compareTo()方法,后面添
    加的所有元素都會調(diào)用compareTo()方法進(jìn)行比較。
    因為只有相同類的兩個實例才會比較大小,所以向 TreeSet 中添加的應(yīng)該是同一個類的對象。
    對于 TreeSet 集合而言,它判斷兩個對象是否相等的唯一標(biāo)準(zhǔn)是:兩個對象通過 compareTo(Object obj) 方法比較返回值。
    當(dāng)需要把一個對象放入 TreeSet 中,重寫該對象對應(yīng)的 equals() 方法時,應(yīng)保證該方法與compareTo(Object obj) 方法有一致的結(jié)果:如果兩個對象通過equals() 方法比較返回 true,則通過 compareTo(Object obj) 方法比較應(yīng)返回 0。否則,讓人難以理解。

    排 序—定制排序

    TreeSet的自然排序要求元素所屬的類實現(xiàn)Comparable接口,如果元素所屬的類沒
    有實現(xiàn)Comparable接口,或不希望按照升序(默認(rèn)情況)的方式排列元素或希望按照其它屬性大小進(jìn)行排序,則考慮使用定制排序。定制排序,通Comparator接口來實現(xiàn)。需要重寫compare(T o1,T o2)方法。
    利用int compare(T o1,T o2)方法,比較o1和o2的大小:如果方法返回正整數(shù),則表示o1大于o2;如果返回0,表示相等;返回負(fù)整數(shù),表示o1小于o2。
    要實現(xiàn)定制排序,需要將實現(xiàn)Comparator接口的實例作為形參傳遞給TreeSet的構(gòu)造器。
    此時,仍然只能向TreeSet中添加類型相同的對象。否則發(fā)生ClassCastException異常。
    使用定制排序判斷兩個元素相等的標(biāo)準(zhǔn)是:通過Comparator比較兩個元素返回了0。

    package Java1;import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; /** 向TreeSet中添加數(shù)據(jù),要求是相同類的對象* 兩種排序方式:自然排序(實現(xiàn)comparable接口)和定制排序(Comparator)* * 自然排序中,比較兩個對象是否相同的標(biāo)準(zhǔn)為:compareTo()返回0,不再是equals().*/ public class TreeTest {public static void main(String[] args) {TreeSet set = new TreeSet(); // set.add(123); // set.add(345); // set.add("afafda"); // 添加失敗:不能添加不同類的對象//舉例一 // set.add(123); // set.add(0); // set.add(-8); // set.add(34); // set.add(76); // set.add(353);//舉例二set.add(new User("tom",12));set.add(new User("tom",34));set.add(new User("eom",89));set.add(new User("adm",92));set.add(new User("ghm",16));Comparator com = new Comparator(){@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof User&&o2 instanceof User){User u1 = (User)o1;User u2 = (User)o2;return Integer.compare(u1.getAge(), u2.getAge());}else{throw new RuntimeException("類型不匹配");}}};Iterator it = set.iterator();while(it.hasNext()){System.out.println(it.next());}} }

    User中的comareTo方法

    //按照姓名從小到大排序@Overridepublic int compareTo(Object o) {if(o instanceof User){User user = (User)o;//return this.name.compareTo(user.name);int compare = this.name.compareTo(user.name);if(compare!=0){return compare;}else{return Integer.compare(this.age,user.age);}}else{throw new RuntimeException("類型不匹配!!");}} 新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!

    總結(jié)

    以上是生活随笔為你收集整理的Java Set接口详细讲解 TreeSet的定制排序和自然排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。