国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java集合-Set

xavier / 2508人閱讀

摘要:集合判斷兩個元素的標準是兩個對象通過方法比較相等,并且兩個對象的方法返回值也相等。的集合元素也是有序的,以枚舉值在類內的定義順序來決定集合元素的順序。是所有實現類中性能最好的,但它只能保存同一個枚舉類的枚舉值作為集合元素。

Set集合通常不能記住元素的添加順序。Set不允許包含重復的元素。

Set集合不允許包含相同的元素,如果試圖把兩個相同的元素加入同一個Set集合中,則添加操作失敗,add()方法返回false,且新元素不會被加入。

HashSet類

HashSet按照Hash算法來存儲集合中的元素,因此具有很好的存取和查詢性能。

HashSet特點

不能保證元素的排列順序,順序可能與添加順序不同,順序也有可能發生變化。

HashSet不是同步的,如果多個線程同時訪問一個HashSet,假設有兩個或者兩個以上線程同時修改了HashSet集合時,則必須通過代碼來保證其同步。

集合元素值可以是null;

當HashSet集合中存入一個元素時,HashSet會調用該對象的HashCode()方法來得到該對象的hashCode值,然后根據該hashCode值決定該對象在HashSet中的存儲位置,如果有兩個元素通過equals()方法比較返回true,但他們的hashCode()方法返回值不相等,HashSet將會把他們存在不同位置,依然可以添加成功。

HashSet集合判斷兩個元素的標準是兩個對象通過equals()方法比較相等,并且兩個對象的hashCode()方法返回值也相等。

即使兩個A對象通過equals()方法比較返回true,但HashSet依然把他們當成兩個對象,即使兩個B對象的hashCode()方法返回相同值,但HashSet依然把他們當成兩個對象。

當把一個對象放入HashSet中時,如果需要重寫該對象對應類的equals()方法,則也應該重寫其hashCode()方法,規則是:如果兩個對象通過equals()方法比較返回true,這兩個對象的hashCode值也應該相同。

如果兩個對象通過equals()比較返回true,但這兩個對象的hashCode()方法返回不同的hashCode值時,這將導致HashSet會把這兩個對象保存在Hash表的不同位置,從而使兩個對象都可以添加成功,這就與Set集合規則沖突了。

如果兩個對象的hashCode()值返回的值相同,但他們通過equals()方法比較返回false時更麻煩。因為兩個對象的hashCode值相同,HashSet將試圖把他們保存在同一個位置,但又不行(否則將只剩下一個對象),所以實際上回在這個位置用鏈式結構來保存多個對象;而HashSet訪問集合元素時也是根據元素的hashCode值來快速定位的,如果HashSet中兩個以上的元素具有相同的hashCode值,將會導致性能下降。

Hash算法可以直接根據該元素的hashCode值計算出該元素的存儲位置,從而快速定位該元素。

數組是所有能存儲一組元素里最快的數據結構。

當從HashSet中訪問元素時,HashSet先計算該元素的hashCode值,也就是調用該元素的hashCode()方法的返回值,然后直接到該hashCode值對應的位置去取出該元素。這就是HashSet速度很快的原因。

HashSet中每個能存儲元素的“槽位slot”通常稱為桶bucket,如果有多個元素的hashCode值相同,但他們通過equals方法比較返回false,就需要在一個桶里存放多個元素,就會導致性能下降。

重寫hashCode方法的基本原則。

在程序運行過程中,同一個對象多次調用hashCode()方法應該返回相同的值。

當兩個對象通過equals()方法比較返回true時,hashCode()應該也返回相同值。

對象中用作equals()方法比較標準的實例變量,都應該用于計算hashCode值。

當程序把可變對象添加到HashSet中之后,盡量不要去修改該集合元素中參與計算hashCode()’equals()的實例變量,否則將會導致HashSet無法爭取操作這些集合。

LinkedHashSet類

LinkedHashSet集合也是根據元素的hashCode值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序,LinkedHashSet將會按元素的添加順序來訪問集合里的元素。

同樣不能允許集合元素重復,

public class LinkedHashSetTest {
    public static void main(String[] args) {
        Collection collection = new LinkedHashSet<>();
        collection.add("java");
        collection.add("python");
        //[java, python]
        System.out.println(collection);
        collection.remove("java");
        collection.add("java");
        //[python, java]
        System.out.println(collection);
    }
}
TreeSet類

TreeSet是StortedSet接口的實現類。TreeSet可以保證集合元素處于排序狀態。

public class TreeSetTest {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet<>();
        treeSet.add("5");
        treeSet.add("4");
        treeSet.add("3");
        treeSet.add("2");
        treeSet.add("1");
        System.out.println(treeSet);
        System.out.println(treeSet.first());//1
        System.out.println(treeSet.last());//5
        //返回集合中位于指定元素之前的元素
        System.out.println(treeSet.lower("4"));//3
        //返回集合中位于指定元素之后的元素
        System.out.println(treeSet.higher("4"));//5
        //返回此set的子集,由小于指定元素的元素組成
        SortedSet headSet = treeSet.headSet("4");
        System.out.println(headSet);//[1, 2, 3]
        //返回set的子集。由大于或者等于指定元素的元素組成
        SortedSet tailSet = treeSet.tailSet("4");
        System.out.println(tailSet);//[4, 5]
    }
}

Tree并不是根據元素的插入順序進行排序的,而是根據元素實際的大小來進行排序的。

與HashSet集合采用hash算法來決定元素的存儲位置不同,TreeSet是采用紅黑樹的數據結構來存儲集合元素,TreeSet支持兩種排序方法,自然排序和定制排序。默認下TreeSet采用自然排序。

自然排序

TreeSet會調用集合元素的compareTo(Object o)方法來比較元素之間的大小關系,然后將集合元素按升序排序,這種方式就是自然排序。

如果試圖把一個對象添加到TreeSet時,則該對象的類必須實現comparable接口。否則報錯

public class TreeSetErrorTest {
    public static void main(String[] args) {
        USER user = new USER("", 2);
        TreeSet treeSet = new TreeSet<>();
        //Exception in thread "main" java.lang.ClassCastException: setTest.USER cannot be cast to java.base/java.lang.Comparable
        treeSet.add(user);
    }
}

當試圖把一個對象添加到TreeSet集合時,TreeSet會調用該對象的comparaTo(Object o)方法與集合中的其他元素進行比較,這就要求集合中的其他元素與該元素時同一類的實例,也就是說,向TreeSet中添加的應該是同一個類的對象,否則也會引發ClassCastException異常。

public class TreeSetErrorTest2 {
    public static void main(String[] args) {
        TreeSet set = new TreeSet<>();
        set.add(new String());
        //Exception in thread "main" java.lang.ClassCastException: java.base/java.lang.String cannot be cast to java.base/java.util.Date
        set.add(new Date());
        /*
         * 在添加String時,是沒有錯誤的,當添加Date對象時,TreeSet就會調用該對象的comparaTo方法與集合中的其他元素進行比較--
         * Date對象的comparaTo方法無法與字符串對象比較大小,所以引發異常
         * */
    }
}

TreeSet只能添加同一種類型的對象,

當把一個對象加入TreeSet集合中時,TreeSet調用該對象的compareTo(Obejct o)方法與容器中的其他對象比較大小,然后根據紅黑樹結構找到他的存儲位置,如果兩個對象通過compareTo(Object o)方法比較相等,新對象將無法添加到TreeSet集合中。

TreeSet集合判斷兩個對象是夠相等的唯一標準是:如果通過compareTo方法比較返回0,TreeSet則會認為他們相等,否則就認為他們不相等。

當需要把一個對象放入TreeSet中,重寫該對象對應類的equals方法時,應保證該方法與compareTo方法有一致的結果,其規則是,如果兩個對象通過equals方法比較返回true時,這兩個對象通過compareTo方法比較應返回0;

TreeSet可以刪除沒有被修改實例變量,且不與其他被修改實例變量的對象重復的對象。P309

推薦不要修改放入HashSet和TreeSet集合中元素的關鍵實例變量。

定制排序
public class MSort {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet<>((o1,o2)->{
            M m1 = o1;
            M m2 = o2;
            return Integer.compare(m1.a, m2.a);
        });
        treeSet.add(new M(12));
        treeSet.add(new M(1232));
        treeSet.add(new M(121));
        //[12, 121, 1232]
        System.out.println(treeSet);
    }
}

當通過Comparator對象或Lambda表達式來實現TreeSet的定制排序時,依然不可以向TreeSet中添加類型不同的對象,否則會引發ClassCastException異常,使用定制排序時,TreeSet對集合元素排序不管集合元素本身的大小,而是由Comparator對象或Lambda表達式。負責集合元素的排序規則,TreeSet判斷兩個集合元素相等的標準是:通過Comparator比較兩個元素返回了0,這樣TreeSet不會把第二個元素添加到集合中。

EnumSet類

EnumSet是一個轉為枚舉類設計的集合類,EnumSet中的所有元素都必須是指定枚舉類型的枚舉值,該枚舉值在創建EnumSet時顯示或隱式地指定。EnumSet的集合元素也是有序的,EnumSet以枚舉值在Enum類內的定義順序來決定集合元素的順序。

EnumSet在內部以位向量的形式存儲,這種存儲形式非常緊湊高效,因此EnumSet對象占用內存很小,運行效率好,尤其是在進行批量操作的時候。

EnumSet集合不允許加入NULL;

public class SeasonEnumSetTest {
    public static void main(String[] args) {
        //創建一個EnumSet集合,集合元素是Season的全部枚舉
        EnumSet enumSet = EnumSet.allOf(Season.class);
        System.out.println(enumSet);//[SPTING, SUMMER, FALL, WINTER]
        //創建一個空集合,指定其集合元素是Season類的枚舉類
        EnumSet noneOf = EnumSet.noneOf(Season.class);
        System.out.println(noneOf);//[]
        noneOf.add(Season.FALL);
        noneOf.add(Season.WINTER);
        System.out.println(noneOf);//[FALL, WINTER]
        //利用現有枚舉進行創建EnumSet集合
        EnumSet of = EnumSet.of(Season.SPTING,Season.SUMMER);
        System.out.println(of);//[SPTING, SUMMER]
        //創建幾個從begin到end之間的枚舉作為新集合的元素
        EnumSet range = EnumSet.range(Season.SUMMER, Season.WINTER);
        System.out.println(range);//[SUMMER, FALL, WINTER]
        //range與complementof枚舉值和是Season的全部枚舉
        EnumSet complementOf = EnumSet.complementOf(range);
        System.out.println(complementOf);//[SPTING]
    }
}

當試圖復制一個Collection集合里的元素來創建EnumSet集合時,必須保證Collection集合里的所有元素都是同一個枚舉類的枚舉值。

Set實現類的性能分析

HashSet的性能總是比TreeSet好,特別是最常用的添加,查詢元素等操作,因為TreeSet需要額外的紅黑樹算法來維護集合元素的次序,只有當需要一個保持排序的Set時,才應該使用TreeSet,否則都應該使用HashSet。

LinkedHashSet對于普通的插入,刪除操作,LinkedHashSet比HashSet要略慢一點,這是由維護鏈表所帶來的額外開銷造成的,但由于有了鏈表,遍歷LinkedHashSet會更快。

EnumSet是所有Set實現類中性能最好的,但它只能保存同一個枚舉類的枚舉值作為集合元素。

Set的三個實現類HashSet,TreeSet和EnumSet都是線程不安全的。

如果有多個線程同時訪問Set集合那么需要手動保證該Set集合的同步性。

Collections.synchronizedSortedSet(new TreeSet(...));

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69316.html

相關文章

  • java集合

    摘要:集合類簡介集合類包含在包下集合類存放的是對象的引用,而非對象本身。集合類型主要分為集,列表,映射。返回此有序集合中當前第一個最小的元素。集合中元素被訪問的順序取決于集合的類型。 Java集合類 1.簡介: java集合類包含在java.util包下集合類存放的是對象的引用,而非對象本身。集合類型主要分為Set(集),List(列表),Map(映射)。 1.1 java集合類圖 sho...

    Pluser 評論0 收藏0
  • Java? 教程(Set接口)

    Set接口 Set是一個不能包含重復元素的Collection,它模擬了數學集抽象,Set接口僅包含從Collection繼承的方法,并添加禁止重復元素的限制,Set還為equals和hashCode操作的行為添加了一個更強的契約,允許Set實例有意義地進行比較,即使它們的實現類型不同,如果兩個Set實例包含相同的元素,則它們是相等的。 Java平臺包含三個通用的Set實現:HashSet、Tre...

    Apollo 評論0 收藏0
  • Java? 教程(集合接口)

    集合接口 核心集合接口封裝了不同類型的集合,如下圖所示,這些接口允許獨立于其表示的細節來操縱集合,核心集合接口是Java集合框架的基礎,如下圖所示,核心集合接口形成層次結構。 showImg(https://segmentfault.com/img/bVbntJW?w=402&h=146); Set是一種特殊的Collection,SortedSet是一種特殊的Set,依此類推,另請注意,層次結構...

    elisa.yang 評論0 收藏0
  • 帶你入門 JavaScript ES6 (五) 集合

    摘要:一概述集合是引入的新的內置對象類型,其特點同數學意義的集合,即集合內所有元素不重復元素唯一。數組集合對比數組和集合,數組可以加入重復數據,而集合的所有元素是唯一的不允許重復。因此,適合臨時存放一組對象,以及存放跟對象綁定的信息。 本文同步帶你入門 帶你入門 JavaScript ES6 (五) 集合,轉載請注明出處。 前面我們學習了: for of 變量和擴展語法 塊作用域變量和解構...

    BetaRabbit 評論0 收藏0
  • Java集合框架——Map接口

    摘要:第三階段常見對象的學習集合框架集合在實際需求中,我們常常會遇到這樣的問題,在諸多的數據中,通過其編號來尋找某一些信息,從而進行查看或者修改,例如通過學號查詢學生信息。面試題和的區別是單列集合的頂層接口,有子接口和。 第三階段 JAVA常見對象的學習 集合框架——Map集合 showImg(https://segmentfault.com/img/remote/1460000019683...

    princekin 評論0 收藏0

發表評論

0條評論

xavier

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<