成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java集合框架——Set接口

Ashin / 2706人閱讀

摘要:如果你知道用集合,就用。在集合中常見的數(shù)據(jù)結(jié)構(gòu)底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢底層數(shù)據(jù)結(jié)構(gòu)是鏈表,查詢慢,增刪快底層數(shù)據(jù)結(jié)構(gòu)是哈希表。依賴兩個(gè)方法和底層數(shù)據(jù)結(jié)構(gòu)是二叉樹。

第三階段 JAVA常見對象的學(xué)習(xí) 集合框架——Set接口

List集合的特點(diǎn)是有序的,可重復(fù)的,是不是存在這一種無序,且能保證元素唯一的集合呢?(HashSet )這就涉及到我們今天所要講的Set集合

Set可以理解為行為不同的Collection

(一) 概述及功能 (1) 概述

Collection

List —— 有序(存儲(chǔ)順序和取出順序一致),可重復(fù)

Set—— 無序(存儲(chǔ)順序和取出順序不一致),唯一

我們首先要清楚有序無序,到底是什么意思?

集合所說的序,是指元素存入集合的順序,當(dāng)元素存儲(chǔ)順序和取出順序一致時(shí)就是有序,否則就是無序。

我們一般說的無序是指HashSet,它既不能保證存儲(chǔ)和取出順序一致,更不能保證自然順序(a-z),而TreeSet 是可以實(shí)現(xiàn)自然順序的。(HashSet的有無序問題可是個(gè)大問題,下一篇專篇講解)

(2) 功能
A:基本功能:(繼承而來)
//添加功能
boolean add(E e):如果指定的元素不存在,則將其指定的元素添加(可選操作) 
boolean addAll(Collection c):將指定集合中的所有元素添加到此集合

//刪除功能
void clear():移除集合中的所有元素
boolean remove(Object o):從集合中移除指定的元素
boolean removeAll(Collection c):從集合中移除一個(gè)指定的集合元素(有一個(gè)就返回true)

//長度功能
int size();

//判斷功能
boolean isEmpty():判斷集合是否為空
boolean contains(Object o):判斷集合中是否包含指定元素
boolean containsAll(Collection c):判斷集合中是否包含指定的一個(gè)集合中的元素
boolean retainAll(Collection c):僅保留該集合中包含在指定集合中的元素

//獲取Set集合的迭代器:
Iterator iterator();

//把集合轉(zhuǎn)換成數(shù)組
Object[] toArray():返回一個(gè)包含此集合中所有元素的數(shù)組
 T[] toArray(T[] a):同上,返回的數(shù)組的運(yùn)行時(shí)類型是指定數(shù)組的運(yùn)行時(shí)類型
    
B:特有功能:
//判斷元素是否重復(fù),為子類提高重寫方法
boolean equals(Object o):將指定的對象與此集合進(jìn)行比較以實(shí)現(xiàn)相等
int hashCode();:返回此集合的哈希碼值

Set集合中的方法用法并不難,可以參照前面Collection、List集合的講解,對照學(xué)習(xí),我們重點(diǎn)講解Set中一些重要的特點(diǎn)。

(二) HashSet

一句話記住它:一種沒有重復(fù)元素的無序集合

我們先說說無序是怎么回事,HashSet 它不保證 set 的迭代順序,特別是它不保證該順序恒久不變,也就是說它的存儲(chǔ)順序和取出順序不一致,雖然說它無序,但是,作為集合來說,它肯定有它自己的存儲(chǔ)順序,而你的順序恰好和它的存儲(chǔ)順序一致,這代表不了有序。下一篇專篇講解這一問題!

無序問題由于篇幅較長,我們先放到另一邊

我們先來思考一下,HashSet是如何保證不重復(fù)的呢?

通過查看HashSet中add方法的源碼

// HashSet 源碼節(jié)選-JKD8
public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

我們可以看到HashSet中add方法所調(diào)用的是HashMap中的put方法,我們定位過去

由于解釋篇幅較長,直接給出結(jié)論,具體源碼解釋在HashMap源碼分析中具體講解

這個(gè)方法底層主要依賴 兩個(gè)方法:hashCode()和equals()。

步驟:

HashSet方法調(diào)用add方法時(shí),調(diào)用hashCode(),得到一個(gè)哈希值,判斷哈希值是否相同。

相同:執(zhí)行equals()方法

? 返回true:說明元素重復(fù),就不添加

? 返回false:說明元素不重復(fù),就添加到集合

不同:就直接把元素添加到集合

現(xiàn)在大家可能想問一句,只使用hashCode()來判斷是否重復(fù)可以嗎?答案是否定的

我們給出這樣一句話:

對象相等則hashCode一定相等,hashCode相等對象未必相等,只有equals返回true,hashCode才相等

如果類沒有重寫這兩個(gè)方法,默認(rèn)使用的Object()。一般來說不會(huì)相同。

而String類重寫了hashCode()和equals()方法,所以,它就可以把內(nèi)容相同的字符串去掉。只留下一個(gè)。

對于String 類型來說,不用重寫 hashCode()方法和equals()方法都可以保證元素的唯一性,但是如果不是Stirng,而是其它自定義的對象就要重寫這兩個(gè)方法才能保證元素的唯一性。

(三) TreeSet 概述:

TreeSet:底層是二叉樹結(jié)構(gòu)(紅黑樹是一種自平衡的二叉樹)

如何存儲(chǔ)

那么這一種結(jié)構(gòu)又是如何存儲(chǔ)元素的呢?(我們將上圖中圓圈稱為節(jié)點(diǎn))

第一個(gè)元素存儲(chǔ)的時(shí)候,直接作為根節(jié)點(diǎn)存儲(chǔ)

第二個(gè)元素開始,每個(gè)元素從根節(jié)點(diǎn)開始比較

若大 則作為右孩子

若小 則作為左孩子

相等 則不作處理

我們來舉一個(gè)例子看看:

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo {
    public static void main(String[] args) {
        Set ts = new TreeSet();
        ts.add(20);
        ts.add(18);
        ts.add(23);
        ts.add(22);
        ts.add(17);
        ts.add(24);
        ts.add(19);
        ts.add(18);
        ts.add(24);

        for (Integer i : ts) {
            System.out.print(i + " ");
        }
    }
}

//運(yùn)行結(jié)果
17 18 19 20 22 23 24 

我們使用圖片來解釋一下上面的代碼

我們將第一個(gè)數(shù)字20 作為根節(jié)點(diǎn)存放,第二個(gè)數(shù)字18比20小所以放在左邊 23大放在右邊

例如22這個(gè)數(shù)字是如何放到如圖的位置呢?

首先22先和20比較是大的所以放到右邊,接著繼續(xù)和23進(jìn)行比較是小的,所以放到23的左邊,接下來同理

我們看到運(yùn)行結(jié)果,很神奇的是按照順序輸出的,這也正符合了我們一開始給出的結(jié)論:TreeSet 是可以實(shí)現(xiàn)自然順序的

如何取出

那么TreeSet中元素是如何取出來的呢?

從根節(jié)點(diǎn)開始,按照左,中,右的原則依次取出元素即可

分析:我們的根節(jié)點(diǎn)是20,所以先看左邊也就是18,但是下面還有子節(jié)點(diǎn),我們繼續(xù)看左邊所以第一個(gè)數(shù)字就是17,然后再看中和右也就是18和19,這時(shí)候根節(jié)點(diǎn)的左邊也就全部看完了,所以接著就是中間的根節(jié)點(diǎn)20,右邊同理。

如何存儲(chǔ)自定義對象

我們設(shè)定一種場景,存儲(chǔ)學(xué)生類中的學(xué)生對象,并且按照年齡從小到大排序(自然排序)

當(dāng)滿足所有成員變量的值都相同的時(shí)候即為同一個(gè)元素

注意:如果一個(gè)類的元素要想能夠進(jìn)行自然排序,就必須實(shí)現(xiàn)自然排序接口(關(guān)鍵)

public class Student implements Comparable {
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

    @Override
    public int compareTo(Student s) {
        //按照年齡排序
        //年齡相同的時(shí)候,去看姓名是否也相同
        //String 默認(rèn)實(shí)現(xiàn)了Comparavle接口,所以可以直接使用字符串的compareTo方法
        int num = this.age - s.age;
        int num2 = num == 0 ? this.name.compareTo(s.name) : num;
        return num2;
    }
}
import java.util.Set;
import java.util.TreeSet;

public class StudentDemo {
    public static void main(String[] args) {
        Set ts = new TreeSet();
        Student s1 = new Student("張三",27);
        Student s2 = new Student("李四",16);
        Student s3 = new Student("王五",40);
        Student s4 = new Student("馬六",40);
        Student s5 = new Student("馬六",40);

        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);

        for (Student s : ts){
            System.out.println(s);
        }

    }
}

//運(yùn)行結(jié)果
Student{name="李四", age=16}
Student{name="張三", age=27}
Student{name="王五", age=40}
Student{name="馬六", age=40}

我們可以專門定義了一個(gè)類MyComparator,其實(shí)也可以省略這一個(gè)類,直接在TreeSetDemo測試類中定義一個(gè)匿名內(nèi)部類

package cn.bwh_04_TreeSet;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class StudentDemo2 {
    public static void main(String[] args) {
        Set ts = new TreeSet(new Comparator() {
            @Override
            public int compare(Student2 s1, Student2 s2) {
                //姓名長度
                int num = s1.getName().length() - s2.getName().length();
                //姓名內(nèi)容
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                //年齡
                int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
                return num3;
            }
        });
        Student2 s1 = new Student2("張三", 27);
        Student2 s2 = new Student2("李四", 16);
        Student2 s3 = new Student2("王五", 40);
        Student2 s4 = new Student2("馬六", 40);
        Student2 s5 = new Student2("馬六", 40);

        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);

        for (Student2 s : ts) {
            System.out.println(s);
        }
    }
}
Collection 集合總結(jié)

Collection集合應(yīng)用時(shí)的選擇

是否唯一

唯一:Set

需要排序:TreeSet

不需要排序:HashSet

如果你知道是Set,但是不知道是哪個(gè)Set,就用HashSet。

不唯一:List

需要安全:Vector

不需要安全:ArrayList或者LinkedList

查詢多:ArrayList

增刪多:LinkedList

如果三原則

如果你知道是List,但是不知道是哪個(gè)List,就用ArrayList。

如果你知道是Collection集合,但是不知道使用誰,就用ArrayList。

如果你知道用集合,就用ArrayList。

在集合中常見的數(shù)據(jù)結(jié)構(gòu)

ArrayXxx:底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢

LinkedXxx:底層數(shù)據(jù)結(jié)構(gòu)是鏈表,查詢慢,增刪快

HashXxx:底層數(shù)據(jù)結(jié)構(gòu)是哈希表。依賴兩個(gè)方法:hashCode()和equals()

TreeXxx:底層數(shù)據(jù)結(jié)構(gòu)是二叉樹。兩種方式排序:自然排序和比較器排序

結(jié)尾:

如果內(nèi)容中有什么不足,或者錯(cuò)誤的地方,歡迎大家給我留言提出意見, 蟹蟹大家 !^_^

如果能幫到你的話,那就來關(guān)注我吧?。ㄏ盗形恼戮鶗?huì)在公眾號(hào)第一時(shí)間更新)

在這里的我們素不相識(shí),卻都在為了自己的夢而努力 ?

一個(gè)堅(jiān)持推送原創(chuàng)Java技術(shù)的公眾號(hào):理想二旬不止

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/75195.html

相關(guān)文章

  • Java? 教程(集合接口

    集合接口 核心集合接口封裝了不同類型的集合,如下圖所示,這些接口允許獨(dú)立于其表示的細(xì)節(jié)來操縱集合,核心集合接口是Java集合框架的基礎(chǔ),如下圖所示,核心集合接口形成層次結(jié)構(gòu)。 showImg(https://segmentfault.com/img/bVbntJW?w=402&h=146); Set是一種特殊的Collection,SortedSet是一種特殊的Set,依此類推,另請注意,層次結(jié)構(gòu)...

    elisa.yang 評(píng)論0 收藏0
  • Java集合框架——Map接口

    摘要:第三階段常見對象的學(xué)習(xí)集合框架集合在實(shí)際需求中,我們常常會(huì)遇到這樣的問題,在諸多的數(shù)據(jù)中,通過其編號(hào)來尋找某一些信息,從而進(jìn)行查看或者修改,例如通過學(xué)號(hào)查詢學(xué)生信息。面試題和的區(qū)別是單列集合的頂層接口,有子接口和。 第三階段 JAVA常見對象的學(xué)習(xí) 集合框架——Map集合 showImg(https://segmentfault.com/img/remote/1460000019683...

    princekin 評(píng)論0 收藏0
  • JAVA 集合框架

    摘要:接口下面包含等。但是接口并沒有繼承接口,因此無法迭代。分離出接口是迭代器模式。但是接口又提供了接口以后將轉(zhuǎn)換成集合來迭代。的增強(qiáng)循環(huán)也只適用于那些繼承了接口的。 Iterator接口是Collection接口的父接口。Collection接口下面包含List,Set,Queue等。 Map接口與Collection接口同級(jí)。但是Map接口并沒有繼承Iterator接口,因此無法迭代。 ...

    galaxy_robot 評(píng)論0 收藏0
  • 集合框架知識(shí)系列01 總體框架

    摘要:集合工具包是在包中,實(shí)現(xiàn)了數(shù)據(jù)結(jié)構(gòu)數(shù)組棧鏈表隊(duì)列映射和集合。集合主要可以劃分為個(gè)部分列表集合映射工具類迭代器枚舉類和。集合的框架圖如下圖片來源集合頂層接口主要有和。和都是集合遍歷相關(guān)接口,是特有的遍歷工具接口 Java集合工具包是在java.util.*包中,實(shí)現(xiàn)了數(shù)據(jù)結(jié)構(gòu):數(shù)組、棧、鏈表、隊(duì)列、映射和集合。Java集合主要可以劃分為4個(gè)部分:List列表、Set集合、Map映射、工具...

    honhon 評(píng)論0 收藏0
  • Java 基礎(chǔ) | Collection 集合概覽

    摘要:說到復(fù)盤基礎(chǔ),并不是所有的都會(huì)復(fù)盤,沒那個(gè)時(shí)間更沒那個(gè)必要。比如,一些基礎(chǔ)的語法以及條件語句,極度簡單。思前想后,我覺得整個(gè)計(jì)劃應(yīng)該從集合開始,而復(fù)盤的方式就是讀源碼。通常,隊(duì)列不允許隨機(jī)訪問隊(duì)列中的元素。 ?showImg(https://segmentfault.com/img/remote/1460000020029737?w=1080&h=711); 老讀者都知道,我是自學(xué)轉(zhuǎn)行...

    codergarden 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<