Set 、HashSet、TreeSet、LinkedHashSet、EnumSet
Set
- 底層原理:
java中set及其子類都是由對(duì)應(yīng)的Map實(shí)現(xiàn)的,如HashSet由HashMap實(shí)現(xiàn),TreeSet由TreeMap實(shí)現(xiàn)等等。
從上面的代碼可以看出,TreeSet的add函數(shù),底層是TreeMap的put(),key值是TreeSet的自己的key,而value是一個(gè)靜態(tài)常量對(duì)象present。
常見的方法:
| 1 | add( ) ? ? ? ??向集合中添加元素 |
| 2 | clear( ) ? ? ? ?去掉集合中所有的元素 |
| 3 | contains( ) ? ?判斷集合中是否包含某一個(gè)元素 |
| 4 | isEmpty( ) ? ?判斷集合是否為空 |
| 5 | iterator( ) ? ?主要用于遞歸集合,返回一個(gè)Iterator()對(duì)象 |
| 6 | remove( ) ? ?從集合中去掉特定的對(duì)象 |
| 7 | size( ) ? ? ? ?返回集合的大小 |
HashSet
- 底層實(shí)現(xiàn):HashMap
- 底層數(shù)據(jù)結(jié)構(gòu)是:哈希表
- 是否有序:無序:有序指的是表中存儲(chǔ)的位置順序和插入順序是否一致,若一致,則為有序。
- 是否排序:否
- 是否線程安全:否
- 能否存入重復(fù)元素:不能
- 如何保證元素的唯一性:HashCode()與equals():首先把先加入元素的HashCode值與已有元素的進(jìn)行比較,如果不同,直接add,如果相同,則使用equals()比較值是否相等,不相等,則add,相等則丟棄。
- 能否存入空元素:能,但是只能存入一個(gè)null
- 存儲(chǔ)內(nèi)容:僅限對(duì)象:下面的代碼插入的也不是基本類型的,是Integer類型的,所以存儲(chǔ)的是對(duì)象。
- 遍歷方式:Iterator或者for-each或者直接輸出。
代碼為證:
輸出結(jié)果:
1--18--6--10--12-- for-each:1--18--6--10--12-- [1, 18, 6, 10, 12]TreeSet
- 底層實(shí)現(xiàn):TreeMap
- 底層數(shù)據(jù)結(jié)構(gòu):紅黑樹
- 是否排序:是
- 是否有序:否
- 是否線程安全:否
- 能否存入重復(fù)元素:不能
- 能否存入null元素:不能:插入null時(shí)會(huì)報(bào)NullPointerException
- 如何保證元素排序:自然排序和比較器排序
- 如何保證元素唯一:根據(jù)比較的返回值是否是0來決定
- 遍歷方式:Iterator或者for-each或者直接輸出。
有代碼為證:
注意:當(dāng)使用自定義的類時(shí),需要重寫排序規(guī)則,否則會(huì)拋出一個(gè)異常:java.lang.ClassCastException,因?yàn)槲覀儧]有指定比較規(guī)則。可參考:
https://www.cnblogs.com/yzssoft/p/7127894.html
運(yùn)行結(jié)果:
TreeSet的數(shù)字測(cè)試: 0--4--5--6--10--12--13-- TreeSet的字符串測(cè)試: TreeSet的當(dāng)前大小為:6 --apple--book--cook--delete--desk--//這里""是第一個(gè)輸出的LinkedHashSet
- 底層實(shí)現(xiàn):使用LinkedHashMap來保存所有元素,通過計(jì)算HashCode值來確保元素的唯一性。
- 底層數(shù)據(jù)結(jié)構(gòu):雙向鏈表
- 是否有序:是FIFO
- 是否排序:否
- 是否線程安全:否
- 能否存入重復(fù)元素:不能
- 能否存入null:能:即使同時(shí)有多個(gè)null值存入,也不會(huì)報(bào)錯(cuò),但是輸出時(shí)只有最先存入的null值輸出(畢竟也是通過hashCode值來判斷存儲(chǔ)的)。
- 遍歷方式:Iterator或者for-each或者直接輸出。
代碼為證:
運(yùn)行結(jié)果:
LinkedHashSet的數(shù)字測(cè)試: LinkedHashSet的當(dāng)前大小為:8 10--12--null--5--13--4--6--0-- LinkedHashSet的字符串測(cè)試: LinkedHashSet的當(dāng)前大小為:14 10--12--null--5--13--4--6--0--apple--delete--book--cook----desk--EnumSet
- 底層數(shù)據(jù)結(jié)構(gòu):位運(yùn)算:EnumSet在內(nèi)部以位向量的形式存儲(chǔ),這種存儲(chǔ)形式非常緊湊、高效,因此EnumSet對(duì)象占用內(nèi)存很小,而且運(yùn)行效率很好。尤其是進(jìn)行批量操作(如調(diào)用containsAll()和retainAll()方法)時(shí),如果其參數(shù)也是EnumSet集合,則該批量操作的執(zhí)行速度也非常快。
- EnumSet是抽象類,只能通過靜態(tài)工廠方法構(gòu)造EnumSet對(duì)象:EnumSet類沒有暴露任何構(gòu)造器來創(chuàng)建該類的實(shí)例,程序應(yīng)該通過它提供的類方法來創(chuàng)建EnumSet對(duì)象
- 是否允許null元素:不允許:試圖插入 null 元素將拋出 NullPointerException。但是,
試圖測(cè)試是否出現(xiàn) null 元素或移除 null 元素將不會(huì)拋出異常(而且EnumSet類中也不允許有null) - 是否線程安全:否
- 能否存入重復(fù)元素:否(首先枚舉類里就不允許有重復(fù)的元素)
- 是否有序:有序
代碼在下:
運(yùn)行結(jié)果:
es:[a1, a2, a3, a4] es2[a3] es3:[a1, a3] es4:[a2, a3, a4] es5:[a1] es6:a2--a3--a4--另附一篇參考TreeSet(對(duì)自定義的類如何使用TreeSet:需要重寫Hashcode和equale方法,因?yàn)門reeSet中的存放的對(duì)象必須能排序,否則會(huì)報(bào)錯(cuò)。)
package Set;import java.util.Set; import java.util.TreeSet;class Student1 implements Comparable<Student1>{int id;public Student1(int id) {this.id = id;}@Overridepublic String toString() {return this.id+"";}@Overridepublic int hashCode() {return this.id;}@Overridepublic boolean equals(Object obj) {if (obj instanceof Student1){Student1 stu = (Student1) obj;if (stu.id == this.id)return true;}return false;}public int compareTo(Student1 o) {return (this.id-o.id);} }public class Tree_Set {public static void main(String[] args) {Set<Student1> set = new TreeSet<Student1>();Student1 s1 = new Student1(5);Student1 s2 = new Student1(1);Student1 s3 = new Student1(2);Student1 s4 = new Student1(4);Student1 s5 = new Student1(3);set.add(s1);set.add(s2);set.add(s3);set.add(s4);set.add(s5);for (Student1 s : set) {System.out.println(s);}}}LinkedHashSet:具有HashSet的查詢速度,且內(nèi)部使用鏈表維護(hù)元素的順序(插入的次序)。于是在使用迭代器遍歷Set時(shí),結(jié)果會(huì)按照元素插入的次序顯示。
package Set;import java.util.Iterator;public class LinkedHashSet {public static void main(String[] args) {java.util.LinkedHashSet<String> books = new java.util.LinkedHashSet<String>();books.add("Book1");books.add("Book2");books.add("Book1");System.out.println(books);//刪除 Book1books.remove("Book1");//重新添加 Book1books.add("Book1");System.out.println(books);for(Iterator<String> iter = books.iterator(); iter.hasNext();){Object value = iter.next();System.out.println(value);}} }運(yùn)行結(jié)果:
[Book1, Book2] [Book2, Book1] Book2 Book1因?yàn)長(zhǎng)inkedHashSet是HashSet的子類,因此它不允許集合元素重復(fù)。所以第二個(gè)books.add("Book1");沒有添加進(jìn)去。
Set集合類應(yīng)用場(chǎng)景:
SortedSet s = Collections.synchronizedSortedSet(new TreeSet(…));
總結(jié)
以上是生活随笔為你收集整理的Set 、HashSet、TreeSet、LinkedHashSet、EnumSet的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java基础,没事常看看(一)类、对象、
- 下一篇: Map、HashMap、TreeMap、