Set接口及實現類

1. 概述

在這裏插入圖片描述
Set接口中元素無序,並且都會以某種規則保證存入的元素不出現重複

特點

  1. 不允許存儲重複的元素
  2. 沒有索引,沒有帶索引的方法,也不能使用普通的for循環遍歷
  3. Set集合取出元素的方式可以採用:迭代器、增強for。普通for不行!

Set集合有多個子類,這裏我們介紹其中的HashSetLinkedHashSet這兩個集合。

2. HashSet集合

在這裏插入圖片描述
java.util.HashSetSet接口的一個實現類,它所存儲的元素是不可重複的,並且元素都是無序的(即存取順序不一致)。java.util.HashSet底層的實現其實是一個java.util.HashMap支持.

優點

  • 具有良好的存取和查找性能:HashSet是根據對象的哈希值來確定元素在集合中的存儲位置。
  • 元素唯一性:依賴於:hashCodeequals方法。

特點

  1. 不允許存儲重複的元素
  2. 沒有索引,沒有帶索引的方法,也不能使用普通的for循環遍歷
  3. 是一個無序的集合,存儲元素和取出元素的順序有可能不一致
  4. 底層儲數據的結構:哈希表(查詢的速度非常的快)

代碼:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Demo01Set {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(1);
        // 使用迭代器遍歷set集合【不能用for循環,因爲沒有索引】
        Iterator<Integer> it = set.iterator();
        while(it.hasNext()) {
            Integer n = it.next();
            System.out.println(n);  // 123
        }
        System.out.println("=========================");
        // 增強for遍歷集合
        for (Integer i : set) {  // set.for
            System.out.println(i);
        }
    }
}

結果:

根據結果我們發現數字1只存儲了一個,也就是說重複的元素set集合不存儲。

1
2
3
=========================
1
2
3

3. HashSet存儲自定義類型元素

若想在HashSet集合中存放自定義的對象,那麼想要保證其唯一,就必須重寫hashCode和equals方法建立屬於當前對象的比較方式。

必須重寫hashCode和equals方法

創建自定義Person類

import java.util.Objects;

public class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    //省略getterandsetter方法和構造器
}

測試類

public class Demo03HashSetSavePerson {
    public static void main(String[] args) {
        // 創建HashSet集合存儲Person
        HashSet<Person> set = new HashSet<>();
      
        Person p1 = new Person("小明",18);  
        Person p2 = new Person("小明",18); 
        Person p3 = new Person("小明",19);

        System.out.println(p1.hashCode()); 
        System.out.println(p2.hashCode());  
        System.out.println("=================");

        System.out.println(p1 == p2);
        System.out.println(p1.equals(p2));  // 重寫equals之前比較的是地址值
        System.out.println("=================");

        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);
        // 遍歷
        for (Person p : set) {
            System.out.println(p);
        }
    }
}

結果:

  • 未重寫:
1355531311
1967205423
42121758
=================
false
false
=================
com.luis.demo03.Set.Person@50cbc42f
com.luis.demo03.Set.Person@282ba1e
com.luis.demo03.Set.Person@75412c2f
  • 重寫後:
23458772
23458772
23458773
=================
false
true
=================
com.luis.demo03.Set.Person@165f3d5
com.luis.demo03.Set.Person@165f3d4

4. LinkedHashSet集合

在HashSet下面有一個子類java.util.LinkedHashSet,它是**鏈表和哈希表(數組+鏈表/紅黑樹)**組合的一個數據存儲結構。可保證集合元素的有序。

演示代碼如下:

import java.util.HashSet;
import java.util.LinkedHashSet;

public class Demo04LinkedHashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("www");
        set.add("abc");
        set.add("abc");
        set.add("itcast");

        System.out.println(set);  // [abc, www, itcast] 無序的,不允許重複
        System.out.println("==============");

        LinkedHashSet<String> linked = new LinkedHashSet<>();
        linked.add("www");
        linked.add("abc");
        linked.add("abc");
        linked.add("itcast");

        System.out.println(linked);  // [www, abc, itcast]  有序的,不允許重複
    }
}

結果:

[abc, www, itcast]
==================
[www, abc, itcast]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章