偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java集合框架總結(jié):Set接口的使用

開發(fā) 后端
Set集合里多個(gè)對(duì)象之間沒有明顯的順序。具體詳細(xì)方法請(qǐng)參考API文檔(可見身邊隨時(shí)帶上API文檔有多重要),基本與Collection方法相同。只是行為不同(Set不允許包含重復(fù)元素)。

1、Set接口的使用

Set集合里多個(gè)對(duì)象之間沒有明顯的順序。具體詳細(xì)方法請(qǐng)參考API文檔(可見身邊隨時(shí)帶上API文檔有多重要),基本與Collection方法相同。只是行為不同(Set不允許包含重復(fù)元素)。

Set集合不允許重復(fù)元素,是因?yàn)镾et判斷兩個(gè)對(duì)象相同不是使用==運(yùn)算符,而是根據(jù)equals方法。即兩個(gè)對(duì)象用equals方法比較返回true,Set就不能接受兩個(gè)對(duì)象。

  1. public class TestSet  
  2. {  
  3.     public static void main(String[] args)   
  4.     {  
  5.         Set<String> books = new HashSet<String>();  
  6.           
  7.         //添加一個(gè)字符串對(duì)象  
  8.         books.add(new String("Struts2權(quán)威指南"));  
  9.           
  10.         //再次添加一個(gè)字符串對(duì)象,  
  11.         //因?yàn)閮蓚€(gè)字符串對(duì)象通過equals方法比較相等,所以添加失敗,返回false  
  12.         boolean result = books.add(new String("Struts2權(quán)威指南"));  
  13.           
  14.         System.out.println(result);  
  15.           
  16.         //下面輸出看到集合只有一個(gè)元素  
  17.         System.out.println(books);    
  18.     }  

程序運(yùn)行結(jié)果:

  1. false  
  2. [Struts2權(quán)威指南] 

說明:程序中,book集合兩次添加的字符串對(duì)象明顯不是一個(gè)對(duì)象(程序通過new關(guān)鍵字來創(chuàng)建字符串對(duì)象),當(dāng)使用==運(yùn)算符判斷返回false,使用equals方法比較返回true,所以不能添加到Set集合中,最后只能輸出一個(gè)元素。

Set接口中的知識(shí),同時(shí)也適用于HashSet、TreeSet和EnumSet三個(gè)實(shí)現(xiàn)類。

2、HashSet類

HashSet按Hash算法來存儲(chǔ)集合的元素,因此具有很好的存取和查找性能。

 HashSet的特點(diǎn):

(1)HashSet不是同步的,多個(gè)線程訪問是需要通過代碼保證同步

(2)集合元素值可以使null。

HashSet集合判斷兩個(gè)元素相等的標(biāo)準(zhǔn)是兩個(gè)對(duì)象通過equals方法比較相等,并且兩個(gè)對(duì)象的hashCode()方法返回值也相等。

  1. //類A的equals方法總是返回true,但沒有重寫其hashCode()方法  
  2. class A  
  3. {  
  4.     public boolean equals(Object obj)  
  5.     {  
  6.         return true;  
  7.     }  
  8. }  
  9. //類B的hashCode()方法總是返回1,但沒有重寫其equals()方法  
  10. class B  
  11. {  
  12.     public int hashCode()  
  13.     {  
  14.         return 1;  
  15.     }  
  16. }  
  17. //類C的hashCode()方法總是返回2,但沒有重寫其equals()方法  
  18. class C  
  19. {  
  20.     public int hashCode()  
  21.     {  
  22.         return 2;  
  23.     }  
  24.     public boolean equals(Object obj)  
  25.     {  
  26.         return true;  
  27.     }  
  28. }  
  29. public class TestHashSet  
  30. {  
  31.     public static void main(String[] args)   
  32.     {  
  33.         HashSet<Object> books = new HashSet<Object>();  
  34.         //分別向books集合中添加2個(gè)A對(duì)象,2個(gè)B對(duì)象,2個(gè)C對(duì)象  
  35.         books.add(new A());  
  36.         books.add(new A());  
  37.         books.add(new B());  
  38.         books.add(new B());  
  39.         books.add(new C());  
  40.         books.add(new C());  
  41.         System.out.println(books);  
  42.     }  

程序運(yùn)行結(jié)果:

  1. [B@1, B@1, C@2, A@b5dac4, A@9945ce] 

說明:

(1)Object類提供的toString方法總是返回該對(duì)象實(shí)現(xiàn)類的類名+@+hashCode(16進(jìn)制數(shù))值,所以可以看到上面程序輸出的結(jié)果。可以通過重寫toString方法來輸出自己希望的形式。

(2)即使2個(gè)A對(duì)象通過equals比較返回true,但HashSet依然把它們當(dāng)成2個(gè)對(duì)象;即使2個(gè)B對(duì)象的hashCode()返回相同值,但HashSet依然把它們當(dāng)成2個(gè)對(duì)象。即如果把一個(gè)對(duì)象放入HashSet中時(shí),如果重寫該對(duì)象equals()方法,也應(yīng)該重寫其hashCode()方法。其規(guī)則是:如果2個(gè)對(duì)象通過equals方法比較返回true時(shí),這兩個(gè)對(duì)象的hashCode也應(yīng)該相同。

 hash算法的功能:

它能保證通過一個(gè)對(duì)象快速查找到另一個(gè)對(duì)象。hash算法的價(jià)值在于速度,它可以保證查詢得到快速執(zhí)行。

當(dāng)需要查詢集合中某個(gè)元素時(shí),hash算法可以直接根據(jù)該元素的值得到該元素保存位置,從而可以讓程序快速找到該元素。

當(dāng)從HashSet中訪問元素時(shí),HashSet先計(jì)算該元素的hashCode值(也就是調(diào)用該對(duì)象的hashCode())方法的返回值),然后直接到該hashCode對(duì)應(yīng)的位置去取出該元素。

即也是快速的原因。HashSet中每個(gè)能存儲(chǔ)元素的“曹位(slot)”通常稱為“桶(bucket)”,如果多個(gè)元素的hashCode相同,但它們通過equals()方法比較返回false,就需要一個(gè)“桶”里放多個(gè)元素,從而導(dǎo)致性能下降。

繼續(xù)深入研究HashSet:

當(dāng)向HashSet中添加一個(gè)可變對(duì)象后,并且后面程序修改了該可變對(duì)象的屬性,可能導(dǎo)致它與集合中其他元素相同,這就可能導(dǎo)致HashSet中包含兩個(gè)相同的對(duì)象。

看下面程序:

  1. class R  
  2. {  
  3.     int count;  
  4.     public R(int count)  
  5.     {  
  6.         this.count = count;  
  7.     }  
  8.     public String toString()  
  9.     {  
  10.         return "R(count屬性:" + count + ")";  
  11.     }  
  12.     public boolean equals(Object obj)  
  13.     {  
  14.         if (obj instanceof R)  
  15.         {  
  16.             R r = (R)obj;  
  17.             if (r.count == this.count)  
  18.             {  
  19.                 return true;  
  20.             }  
  21.         }  
  22.         return false;  
  23.     }  
  24.     public int hashCode()  
  25.     {  
  26.         return this.count;  
  27.     }  
  28. }  
  29. public class TestHashSet2  
  30. {  
  31.     public static void main(String[] args)   
  32.     {  
  33.         HashSet<R> hs = new HashSet<R>();  
  34.         hs.add(new R(5));  
  35.         hs.add(new R(-3));  
  36.         hs.add(new R(9));  
  37.         hs.add(new R(-2));  
  38.         //打印TreeSet集合,集合元素是有序排列的  
  39.         System.out.println(hs);  
  40.         //取出第一個(gè)元素  
  41.         Iterator<R> it = hs.iterator();  
  42.         R first = (R)it.next();     //first指向集合的第一個(gè)元素  
  43.         //為第一個(gè)元素的count屬性賦值  
  44.         first.count = -3;           //first指向的元素值發(fā)生改變,地址并沒有改變,大家可以試著用Java內(nèi)存分配機(jī)制(棧和堆)思考下。  
  45.         //再次輸出count將看到HashSet里的元素處于無序狀態(tài)  
  46.         System.out.println(hs);  
  47.         hs.remove(new R(-3));  
  48.         System.out.println(hs);  
  49.         //輸出false  
  50.         System.out.println("hs是否包含count為-3的R對(duì)象?" + hs.contains(new R(-3)));  
  51.         //輸出false  
  52.         System.out.println("hs是否包含count為5的R對(duì)象?" + hs.contains(new R(5)));  
  53.  
  54.     }  

程序運(yùn)行結(jié)果:

  1. [R(count屬性:5), R(count屬性:9), R(count屬性:-3), R(count屬性:-2)]  
  2. [R(count屬性:-3), R(count屬性:9), R(count屬性:-3), R(count屬性:-2)]  
  3. [R(count屬性:-3), R(count屬性:9), R(count屬性:-2)]  
  4. hs是否包含count為-3的R對(duì)象?false 
  5. hs是否包含count為5的R對(duì)象?false 

說明:程序重寫了R類的equals()和hashCode()方法,這兩個(gè)方法都是根據(jù)R對(duì)象的count屬性來判斷。從運(yùn)行結(jié)果可以看出,HashSet集合中有完全相同元素,這表明兩個(gè)元素已經(jīng)重復(fù),但因?yàn)镠ashSet在添加它們時(shí)已經(jīng)把它們添加到了不同地方,所以HashSet完全可以容納兩個(gè)相同元素。至于第一個(gè)count為-3的R對(duì)象,它保存在count為5的R對(duì)象對(duì)應(yīng)的位置(地址)。當(dāng)向HashSet中添加可變對(duì)象時(shí),必須十分小心。如果修改HashSet集合中的對(duì)象,有可能導(dǎo)致該對(duì)象與集合中其他對(duì)象相等,從而導(dǎo)致HashSet無法準(zhǔn)確訪問該對(duì)象。

HashSet還有一個(gè)子類LinkedHashSet,LinkedHashSet集合也根據(jù)元素hashCode值來決定元素存儲(chǔ)位置,但它同時(shí)使用鏈表維護(hù)元素的次序,即當(dāng)遍歷LinkedHashSet集合元素時(shí),HashSet將會(huì)按元素的添加順序來訪問集合里的元素。

3、TreeSet類

TreeSet是SortedSet接口的唯一實(shí)現(xiàn),TreeSet可以確保集合元素處于排序狀態(tài)(元素是有序的)。

TreeSet提供的幾個(gè)額外方法:

  1. Comparator comparttor(): 返回當(dāng)前Set使用的Compara投入,或者返回null,表示以自然方式排序。  
  2.  
  3. Object first():返回集合中的第一個(gè)元素。  
  4.  
  5. Object last():返回集合中的最后一個(gè)元素。  
  6.  
  7. Objiect lower(Object e):返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,參考元素可以不是TreeSet的元素)。  
  8.  
  9. Object higher(Object e):返回集合中位于指定元素之后的元素(即大于指定元素的最小元素,參考元素可以不需要TreeSet的元素)。  
  10.  
  11. SortedSet subSet(fromElement, toElement):返回此Set的子集,范圍從fromElement(包含大于等于)到toElement(不包含小于)。  
  12.  
  13. SortedSet headSet(toElement):返回此Set的子集,由小于toElement的元素組成。  
  14.  
  15. SortedSet tailSet(fromElement):返回此Set的子集,由大于或等于fromElement的元素組成。 
  1. public class TestTreeSetCommon  
  2. {  
  3.     public static void main(String[] args)   
  4.     {  
  5.         TreeSet<Integer> nums = new TreeSet<Integer>();  
  6.         //向TreeSet中添加四個(gè)Integer對(duì)象  
  7.         nums.add(5);  
  8.         nums.add(2);  
  9.         nums.add(10);  
  10.         nums.add(-9);  
  11.         //輸出集合元素,看到集合元素已經(jīng)處于排序狀態(tài)  
  12.         System.out.println(nums);  
  13.         //輸出集合里的第一個(gè)元素  
  14.         System.out.println(nums.first());  
  15.         //輸出集合里的最后一個(gè)元素  
  16.         System.out.println(nums.last());  
  17.         //返回小于4的子集,不包含4  
  18.         System.out.println(nums.headSet(4));  
  19.         //返回大于5的子集,如果Set中包含5,子集中還包含5  
  20.         System.out.println(nums.tailSet(5));  
  21.         //返回大于等于-3,小于4的子集。  
  22.         System.out.println(nums.subSet(-3 , 4));  
  23.     }  

說明:由運(yùn)行結(jié)果可以看出,TreeSet并不是根據(jù)元素的插入順序進(jìn)行排序,而是根據(jù)元素實(shí)際值來進(jìn)行排序。TreeSet采用紅黑樹的數(shù)據(jù)結(jié)構(gòu)對(duì)元素進(jìn)行排序,具體排序內(nèi)容會(huì)在后續(xù)文章中說明。

原文鏈接:http://www.cnblogs.com/zhxxcq/archive/2012/03/14/2395511.html

【編輯推薦】

  1. Java的位移運(yùn)算巧方法
  2. Java7的一個(gè)新類JLayer:裝飾的Swing組件
  3. 關(guān)于Java中內(nèi)存溢出的解決辦法
  4. Java中的面向?qū)ο筇匦?/a>
  5. 探究Java初始化的過程
責(zé)任編輯:林師授 來源: 星星傳奇的博客
相關(guān)推薦

2012-03-12 15:36:29

Java框架

2019-07-22 09:59:20

Java框架集合

2012-05-02 10:47:51

JavaJava集合框架

2021-04-12 07:34:03

Java集合框架

2015-09-11 09:40:35

Java集合框架

2011-04-14 09:30:15

集合框架

2012-04-26 10:52:52

Java數(shù)組集合

2011-07-11 11:02:12

JAVA集合框架

2021-03-11 07:27:22

Java 集合數(shù)據(jù)

2009-06-29 16:50:27

Java集合框架

2023-10-09 07:57:14

JavaJCF

2020-06-15 11:04:38

JavaScript 代碼JavaScript

2009-06-30 14:01:00

Java集合框架Java數(shù)組排序

2015-12-24 10:13:29

JavaExecutor框架

2015-11-06 10:26:53

JavaExecutor框架

2023-12-01 11:13:50

JavaTreeSet

2010-06-11 17:10:02

Java框架開源

2019-11-14 09:53:30

Set集合存儲(chǔ)

2015-09-11 09:17:55

JavaJava HashMa

2020-01-09 09:56:47

Java集合框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)