1. 程式人生 > 實用技巧 >Java基礎(十七)——Set集合、可變引數和Collections工具類

Java基礎(十七)——Set集合、可變引數和Collections工具類

Set介面

  java.util.set介面和java.util.List介面是一樣的,都是繼承自Collection介面,它與collection介面中的方法基本一樣,沒有對Collection介面進行功能上的擴充套件,只是比Collection介面更加嚴格。與List介面不同的是,Set介面中的元素是無序的,並且都會以某種規則保證存入的元素不重複。

  Set集合取出元素的方式可以採用:迭代器、增強for迴圈。

HashSet集合介紹

  java.util.HashSet是Set介面的一個實現類,它儲存的元素是不可重複的,並且元素都是無序的(存取順序不一致)。java.util.HashSet

底層的實現其實是一個java.util.HashMap支援的。

  HashSet是根據物件的雜湊值來確定元素在集合當中的儲存位置,因此它具有良好的存取和查詢效能。保證元素唯一性的方式依賴於hashCodeequals方法。

HashSet集合儲存資料的結構(雜湊表)

  什麼是雜湊表呢?

  在JDK1.8之前,雜湊表的底層採用的是陣列+連結串列實現,即使用連結串列處理雜湊衝突,同一雜湊值的連結串列都儲存在一個連結串列裡,但是當位於一個鏈中的元素較多時,即hash值相等的元素較多時,通過key值依次查詢的效率很低下。在JDK1.8中,雜湊表儲存結構採用陣列+連結串列/紅黑樹實現的,當連結串列的長度超過閾值(8)時,將連結串列轉換成紅黑樹結構,這樣的好處是大大減少了查詢的時間。

  如圖展示:

  總而言之,JDK1.8之後引入紅黑樹結構大大優化了HashMap的效能,那麼對於我們來講保證HashSet元素唯一不重複,其實是根據物件的hashCode和equals方法來決定的。如果我們往集合當中儲存的是自定義的物件,需要保證物件的唯一性,就必須重寫hashCode和equals方法,來自定義當前的物件的比較方式。

  HashSet保證元素唯一的原理,如圖所示

HashSet儲存自定義型別的元素

    一般需要重寫物件當中的hashCode和equals方法,建立自己的比較方式。才能保證HashSet集合中元素的唯一性。

  程式碼示例:

 1 @Override
2 public boolean equals(Object o) { 3 if (o == null) { 4 return false; 5 } 6 if (this == o) { 7 return true; 8 } 9 // 向下轉型 型別判斷 10 if (o instanceof Student) { 11 Student student = (Student)o; 12 // 同名同年齡的人為同一個人 true 13 return student.getName().equals(name) && student.getAge() == age; 14 } 15 return false; 16 } 17 18 @Override 19 public int hashCode(){ 20 // 使用Objects類中的hash方法 21 return Objects.hash(name,age); 22 }

LinkedHashSet集合

  我們知道HashSet保證元素的唯一,可是存進去的元素是沒有順序的,那麼如何保證存進去的元素是有序的?

  在java.util.HashSet類的下面還有一個子類java.util.LinkedHashSet,它是連結串列和雜湊表的組合的一個數據儲存結構。程式碼示例:

    

 1 // 構建一個LinkedHashSet集合物件
 2         LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
 3         linkedHashSet.add("www");
 4         linkedHashSet.add("baidu");
 5         linkedHashSet.add("com");
 6         linkedHashSet.add("abc");
 7         linkedHashSet.add("abc");
 8         linkedHashSet.add("java");
 9         linkedHashSet.add("python");
10         // [www, baidu, com, abc, java, python]
11         System.out.println(linkedHashSet);// [www, baidu, com, abc] 有序的,不重複的

可變引數

   在JDK1.5之後,如果我們定義一個方法需要接受多個引數,並且多個引數的資料型別一致,那麼我們可以簡化成如下格式:

1 修飾符 返回值型別  方法名(引數型別... 形參名){
2     //...
3 }

  其實上面的格式完全等價於:

1 修飾符 返回值型別  方法名(引數型別[] 引數名){
2     //....
3 }

  只是後面的寫法,在方法呼叫,必須傳遞一個數組型別,而前者可以直接傳遞引數資料。

  JDK1.5之後,出現的這種簡化操作。"..."用在引數上,我們稱之為可變引數。

  同樣是代表陣列,但是在方法呼叫這個帶有可變引數時,不用建立陣列,而是直接將陣列當中的元素作為實際引數進行傳遞,其實編譯生成的.class檔案,本質是將這些元素封裝到了一個數組當中,再進行資料傳遞,這些動作都在編譯生成.class檔案的時候,自動完成了。

  程式碼示例:

1  public static void add(int... arr) {
2         //System.out.println(arr);// [I@1b6d3586 底層就是一個數組
3         //System.out.println(arr.length);//0
4         int sum = 0;
5         for (int i = 0; i < arr.length; i++) {
6             sum += arr[i];
7         }
8         System.out.println(sum); // 30
9     }

  Collections集合工具類

    常用功能

  • java.util.Collections是集合工具類,用來操作集合物件中的元素, 方法如下:

  • public static <T> boolean addAll(Collection<? super T> c,T... elements):往集合中一次性新增多個元素。
  • public static <T> void shuffle(List<?> list):打亂集合中的元素順序。
  • public static <T> void sort(List<T> list):將集合中的元素按照預設規則排序。
  • public static <T> void sort(List<T> list,Comparator<? super T> c):將集合中的元素按照指定的規則進行排序。

程式碼演示:

  

 1         ArrayList<String> strs = new ArrayList<>();
 2         //往集合當中儲存元素
 3         /*strs.add("abc");
 4         strs.add("小孫");
 5         strs.add("小劉");
 6         strs.add("小趙");*/
 7 
 8         //使用Collections集合工具類中的addAll
 9         Collections.addAll(strs, "張三","老王","小金豆","孬蛋","老白乾");
10         System.out.println(strs);
11         System.out.println("=========================");
12         Collections.shuffle(strs);
13         System.out.println(strs);    
 1 ArrayList<Integer> list01 = new ArrayList<>();
 2 Collections.addAll(list01, 124,234,566,324,765,342);
 3 System.out.println(list01);
 4        System.out.println("============================");
 5 Collections.sort(list01);
 6 System.out.println(list01);
 7         System.out.println("============================");
 8 ArrayList<String> list02 = new ArrayList<>();
 9         Collections.addAll(list02,"asd","sd","sc","sv","ac","b","vc","v","cs");
10 Collections.shuffle(list02);
11 Collections.sort(list02);
12 System.out.println(list02);