Set集合

??Set集合最大的特點(diǎn)就是不允許保存重復(fù)元素,其也是Collection子接口。

Set接口簡(jiǎn)介

??在JDK1.9以前Set集合與Collection集合的定義并無(wú)差別,Set繼續(xù)使用了Collection接口中提供的方法進(jìn)行操作,但是從JDK1.9后,Set集合也像List集合一樣擴(kuò)充了一些static方法,Set集合的定義如下:

public interface Set<E> extends Collection<E>

??需要注意的是Set集合并不像List集合那樣擴(kuò)充了許多的新方法,所以無(wú)法使用List集合中提供的get()方法,也就是說(shuō)無(wú)法實(shí)現(xiàn)指定索引數(shù)據(jù)的獲取,Set接口的繼承關(guān)系如下。

Set接口

??從JDK1.9后,Set集合也提供了像List集合中類(lèi)似的of()的靜態(tài)方法。下面就使用此方法進(jìn)行Set集合特點(diǎn)的驗(yàn)證。
范例:驗(yàn)證集合特征

import  java.util.Set;
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        //進(jìn)行Set集合數(shù)據(jù)的保存,并設(shè)置有重復(fù)的內(nèi)容
       Set<String> all=Set.of("Hello","World","MLDN","Hello","World");
       all.forEach(System.out::println);
       //Exception in thread "main" java.lang.IllegalArgumentException: duplicate element: Hello
    }
}

當(dāng)使用of()這個(gè)新方法時(shí)如果發(fā)現(xiàn)集合中存在重復(fù)元素則會(huì)直接拋出異常。這與傳統(tǒng)的Set集合不保存重復(fù)元素的特點(diǎn)相一致,只不過(guò)這個(gè)方法拋出了異常。

??Set集合的常規(guī)使用形式一定是依靠子類(lèi)進(jìn)行實(shí)例化的,所以Set接口之中有兩個(gè)常用的子類(lèi):HashSet、TreeSet。

HashSet子類(lèi)

??HashSet是Set接口中使用最多的一個(gè)子類(lèi),其最大的特點(diǎn)就是保存的數(shù)據(jù)時(shí)無(wú)序的,而HashSet類(lèi)的定義:

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable

這種繼承的形式和之前的ArrayList是非常相似的,那么現(xiàn)在來(lái)觀察一下類(lèi)的繼承結(jié)構(gòu):

HashSet

范例:觀察HashSet類(lèi)

import java.util.HashSet;
import  java.util.Set;
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
       Set<String> all=new HashSet();
       all.add("Hello");
       all.add("World");
       all.add("MLDN");
       all.add("Hello");
       all.add("World");
       all.add("baidu");
       all.forEach(System.out::println);
        /**
         * Hello
         * baidu
         * World
         * MLDN
         */
    }
}

通過(guò)執(zhí)行結(jié)構(gòu)就可以發(fā)現(xiàn)HashSet的操作特點(diǎn):不允許保存重復(fù)元素(Set接口定義的),另外一個(gè)特點(diǎn)就是HashSet中保存的數(shù)據(jù)時(shí)無(wú)序的。

TreeSet子類(lèi)

??Set的另外一個(gè)子接口就是TreeSet,與HashSet最大區(qū)別在于TreeSet集合中保存的數(shù)據(jù)時(shí)有序的,首先來(lái)觀察TreeSet的定義:

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable

public interface NavigableSet<E> extends SortedSet<E>

public interface SortedSet<E> extends Set<E>

在這個(gè)子類(lèi)中依然繼承了AbstractSet父抽象類(lèi),同時(shí)又實(shí)現(xiàn)了一個(gè)NavigableSet父接口。

TreeSet

范例:使用TreeSet

import java.util.Set;
import java.util.TreeSet;
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
       Set<String> all=new TreeSet();
       all.add("Hello");
       all.add("World");
       all.add("MLDN");
       all.add("Hello");
       all.add("World");
       all.add("baidu");
       all.forEach(System.out::println);
        /**按照字母順序排序
         * Hello
         * MLDN
         * World
         * baidu
         */
    }
}

當(dāng)利用TreeSet保存的數(shù)據(jù)時(shí),所有的數(shù)據(jù)將按照數(shù)據(jù)的升序進(jìn)行自動(dòng)排序處理。

TreeSet排序說(shuō)明

??經(jīng)過(guò)分析后發(fā)現(xiàn),TreeSet類(lèi)中保存的數(shù)據(jù)時(shí)允許排序的,但是這個(gè)類(lèi)必須要實(shí)現(xiàn)Comparable接口,只有實(shí)現(xiàn)了此接口才能夠確認(rèn)出對(duì)象的大小關(guān)系。

TreeSet本質(zhì)上是利用TreeMap類(lèi)實(shí)現(xiàn)的集合數(shù)據(jù)的存儲(chǔ),而TreeMap(樹(shù))就需要根據(jù)Comparable來(lái)確定對(duì)象的大小關(guān)系。

范例:使用自定義的類(lèi)實(shí)現(xiàn)排序的處理操作

import java.util.Set;
import java.util.TreeSet;
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        Set<Person> all=new TreeSet();
        all.add(new Person("張三",19));
        all.add(new Person("李四",21));
        all.add(new Person("王五",20));
        all.add(new Person("李四",21));//數(shù)據(jù)重復(fù)
        all.add(new Person("趙六",19));//年齡相同,但姓名不同
        all.add(new Person("張三",22));//年齡不同,但姓名相同
        all.forEach(System.out::println);
        /**
         * 姓名、張三、年齡:19
         * 姓名、趙六、年齡:19
         * 姓名、王五、年齡:20
         * 姓名、李四、年齡:21
         * 姓名、張三、年齡:22
         */
    }
}
@lombok.AllArgsConstructor//自動(dòng)生成全部參數(shù)的構(gòu)造方法
class Person implements Comparable<Person>{
    private String name;
    private int age;
    @Override
    public String toString() {
        return String.format("姓名、%s、年齡:%s", name, age);
    }
    @Override
    public int compareTo(Person o) {
        if(age!=o.age){
            return age-o.age;
        }
        return name.compareTo(o.name);
    }
}

在使用自定義類(lèi)對(duì)象進(jìn)行比較處時(shí),一定要將該類(lèi)中所有屬性都依次進(jìn)行大小關(guān)系的匹配,否則某一個(gè)或者幾個(gè)屬性相同時(shí)也會(huì)被默認(rèn)認(rèn)為是重復(fù)數(shù)據(jù),所以TreeSet是利用了Comparable接口來(lái)確認(rèn)重復(fù)數(shù)據(jù)的。

??由于TreeSet在操作過(guò)程之中需要將類(lèi)中的所有屬性進(jìn)行比對(duì),這樣的實(shí)現(xiàn)過(guò)于繁瑣,那么在實(shí)際的開(kāi)發(fā)中應(yīng)該首選HashSet子類(lèi)進(jìn)行存儲(chǔ)。

關(guān)于重復(fù)元素的說(shuō)明

??TreeSet類(lèi)是利用了Comparable接口來(lái)實(shí)現(xiàn)了重復(fù)元素的判斷,但是Set集合的整體特征就是不允許保存重復(fù)元素。但是HashSet判斷重復(fù)元素的方式并不是利用Comparable接口完成的,它利用的是Object類(lèi)中提供的方法實(shí)現(xiàn)的:

  • 對(duì)象編碼:public int hashCode();
  • 對(duì)象比較:public boolean equals?(Object obj);

??在進(jìn)行重復(fù)元素判斷時(shí)首先利用hashCode()進(jìn)行編碼的匹配,如果該編碼不存在,則表示數(shù)據(jù)不存在,證明沒(méi)有重復(fù),如果該編碼存在,則進(jìn)一步進(jìn)行對(duì)象比較處理,如果相同,則此數(shù)據(jù)是不允許保存的。

范例:實(shí)現(xiàn)重復(fù)元素處理

@lombok.AllArgsConstructor//自動(dòng)生成全部參數(shù)的構(gòu)造方法
@lombok.Data//會(huì)自動(dòng)生成getter、setter、hashCode、equals、toString等方法
class Person{
    private String name;
    private int age;
}

??在Java程序中,真正的重復(fù)元素的判斷處理利用的就是hashCode和equals()兩個(gè)方法共同作用完成的,而只有在排序要求的情況下(TreeSet)才會(huì)利用Comparable接口來(lái)實(shí)現(xiàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 10.1 Set集合 Set接口繼承Collection接口,沒(méi)有提供額外的方法。Set集合不允許包含相同...
    王毅巽閱讀 384評(píng)論 0 0
  • Java集合類(lèi)可用于存儲(chǔ)數(shù)量不等的對(duì)象,并可以實(shí)現(xiàn)常用的數(shù)據(jù)結(jié)構(gòu)如棧,隊(duì)列等,Java集合還可以用于保存具有映射關(guān)...
    小徐andorid閱讀 2,096評(píng)論 0 13
  • Set接口 set一個(gè)最大的特點(diǎn)就是無(wú)序,無(wú)重復(fù) 今天主要內(nèi)容 HashSetHashSet的工作原理存儲(chǔ)自定義對(duì)...
    須臾之北閱讀 306評(píng)論 0 0
  • 今日任務(wù)1、TreeSet介紹(掌握TreeSet集合的應(yīng)用)2、Comparable 接口介紹(掌握)3、Com...
    Villain丶Cc閱讀 1,964評(píng)論 0 1
  • 前言 Set 接口 Set 集合的常見(jiàn)實(shí)現(xiàn)類(lèi)HashSetHashSet的屬性及函數(shù)TreeSetTreeSet的...
    HikariCP閱讀 407評(píng)論 0 2

友情鏈接更多精彩內(nèi)容