1. 程式人生 > 實用技巧 >Java集合-Set介面

Java集合-Set介面

Collection介面:單列集合,用來儲存一個一個的物件
* (不常用)子介面Set:儲存無序的、不可重複的資料
* HashSet:作為Set介面的主要實現類;執行緒不安全的;可以儲存null值
* LinkedHashSet:作為HashSet的子類,遍歷期內部資料時,可以按照新增的順序遍歷
* TreeSet:可以按照新增物件的指定屬性,進行排序

Set介面
* 無序性:不等於隨機性,無序性相當於List而言,儲存的資料在底層陣列中並非按照陣列索引的順序新增,而是根據資料的雜湊值決定的
* 不可重複性:保證新增的元素按照equals()判斷時,不能返回true。即:相同元素只能新增一個;(類需要重寫equals和hashCode)
*
* 1.Set介面中沒有額外定義的新的方法,使用的都是Collection中宣告的方法。
*
* 2.新增元素的過程
* 我們向HashSet中新增元素a,首先呼叫元素a所在類的hashCode()方法,計算a的雜湊值,
* 此雜湊值接著通過某種演算法計算出在HashSet底層陣列中存放的位置(即為:索引位置),判斷
* 此陣列此位置上是否有元素。
* 如果此位置上沒有其他物件元素,則元素a新增成功;//情況一
* 如果此位置上有其他元素b(或以連結串列形式存在的多個元素),則比較元素a與元素b的hash值:
* 如果hash值不同,則元素a新增成功。--->情況二
* 如果hash值相同,進而呼叫元素a所在類的equals()方法:
* equals()返回true,元素a新增失敗。---->情況三
* equals()返回false,元素a新增成功。---->情況四
* 對於新增成功的情況二、四而言,元素a與已經存在指定索引位置上的資料以連結串列的形式儲存。
* jdk 7:元素a放到陣列中,指向原來的元素
* jdk 8:原來的元素放到陣列中,指向元素a
* 總結:七上八下
*
* HashSet底層:陣列+連結串列的結構


import org.junit.Test;

import
java.util.*; /** * * Collection介面:單列集合,用來儲存一個一個的物件 * (不常用)子介面Set:儲存無序的、不可重複的資料 * HashSet:作為Set介面的主要實現類;執行緒不安全的;可以儲存null值 * LinkedHashSet:作為HashSet的子類,遍歷期內部資料時,可以按照新增的順序遍歷 * TreeSet:可以按照新增物件的指定屬性,進行排序 * @author orz */ public class SetTest { /** *Set介面 * 無序性:不等於隨機性,無序性相當於List而言,儲存的資料在底層陣列中並非按照陣列索引的順序新增,而是根據資料的雜湊值決定的 * 不可重複性:保證新增的元素按照equals()判斷時,不能返回true。即:相同元素只能新增一個;(類需要重寫equals和hashCode) * * 1.Set介面中沒有額外定義的新的方法,使用的都是Collection中宣告的方法。 * * 2.新增元素的過程 * 我們向HashSet中新增元素a,首先呼叫元素a所在類的hashCode()方法,計算a的雜湊值, * 此雜湊值接著通過某種演算法計算出在HashSet底層陣列中存放的位置(即為:索引位置),判斷 * 此陣列此位置上是否有元素。 * 如果此位置上沒有其他物件元素,則元素a新增成功;//情況一 * 如果此位置上有其他元素b(或以連結串列形式存在的多個元素),則比較元素a與元素b的hash值: * 如果hash值不同,則元素a新增成功。--->情況二 * 如果hash值相同,進而呼叫元素a所在類的equals()方法: * equals()返回true,元素a新增失敗。---->情況三 * equals()返回false,元素a新增成功。---->情況四 * 對於新增成功的情況二、四而言,元素a與已經存在指定索引位置上的資料以連結串列的形式儲存。 * jdk 7:元素a放到陣列中,指向原來的元素 * jdk 8:原來的元素放到陣列中,指向元素a * 總結:七上八下 * * HashSet底層:陣列+連結串列的結構 * */ @Test public void test1() { HashSet hashSet = new HashSet(); hashSet.add("AA"); hashSet.add("BB"); hashSet.add("CC"); hashSet.add("CC"); hashSet.add("CC"); Iterator iterator = hashSet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } /** * LinkedHashSet:可以按照新增的順序遍歷 * LinkedHashSet:作為HashSet的子類,再新增資料的同時,每個資料還維護了兩個引用,記錄此資料前一個數據和後一個數據 * 優點:對於頻繁的遍歷操作,效率高於HashSet * */ @Test public void test2() { HashSet hashSet2 = new HashSet(); hashSet2.add(123); hashSet2.add(234); hashSet2.add("AA"); hashSet2.add("BB"); hashSet2.add("CC"); Iterator iterator2 = hashSet2.iterator(); while (iterator2.hasNext()) { System.out.println(iterator2.next()); } System.out.println(); //可以按照新增的順序遍歷 HashSet hashSet = new LinkedHashSet(); hashSet.add(123); hashSet.add(234); hashSet.add("AA"); hashSet.add("BB"); hashSet.add("CC"); Iterator iterator = hashSet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } /**TreeSet和TreeMap採用紅黑樹的儲存結構 * TreeSet: * 1.向TreeSet中新增的資料,要求是相同的物件 * 2.兩種排序方式: * 自然排序(實現Comparable介面):比較兩個物件是否相同的標準為:compareTo()返回0,不再是equals(); * * 定製排序(Comparator):比較兩個物件是否相同的標準為:compare()返回0,不再是equals(); */ @Test public void test3() { TreeSet treeSet = new TreeSet(); //錯誤,不能新增不同類的物件 // treeSet.add(123); // treeSet.add(456); // treeSet.add("AA"); treeSet.add(new Person(21,"Tom")); treeSet.add(new Person(23,"Jack")); treeSet.add(new Person(25,"Jack")); treeSet.add(new Person(43,"Cat")); treeSet.add(new Person(12,"Dog")); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } @Test public void test4() { Comparator com=new Comparator() { @Override public int compare(Object o1, Object o2) { if(o1 instanceof Person && o2 instanceof Person) { Person person=(Person)o1; Person person1=(Person)o2; return Integer.compare(person.getAge(),person1.getAge()); } else { throw new RuntimeException("輸入的資料型別不匹配"); } } }; TreeSet treeSet = new TreeSet(com); treeSet.add(new Person(21,"Tom")); treeSet.add(new Person(23,"Jack")); treeSet.add(new Person(25,"Jack")); treeSet.add(new Person(43,"Cat")); treeSet.add(new Person(12,"Dog")); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }

import java.util.Objects;

public class Person implements Comparable{

    private int age;
    private String name;

    public Person() {
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    @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(age, name);
    }

    //按照姓名從小到大排序,年齡從小到大

   @Override
   public int compareTo(Object o)
   {
       if(o instanceof Person)
       {
           Person person=(Person)o;
          // return this.name.compareTo(person.name);
           int compare=this.name.compareTo(person.name);
           if(compare!=0)
           {
               return compare;
           }
           else
           {
               return Integer.compare(this.age,person.age);
           }

       }
       else
       {
           throw new RuntimeException("輸入的型別不匹配");
       }
   }
}