【Java學(xué)習(xí)】HashSet、HashMap、TreeSet集合的方法|HashSet和HashMap、ArrayList的區(qū)別

心得感悟

這兩天都在學(xué)集合的方法,如果沒理解透,很容易混淆不同的集合的概念和方法,在多番查閱后,總結(jié)了一點(diǎn)集合之間的區(qū)別。雖然老師講課的知識(shí)點(diǎn)是有順序的,但剛聽完課腦子里還是一團(tuán)亂麻,寫博客的確是一個(gè)梳理思路的好辦法,感覺寫博客就像自己當(dāng)老師一樣,如果要去教別人,肯定自己心里要有數(shù)。


內(nèi)容簡(jiǎn)概

  • 一、集合框架圖
  • 二、HashSet集合
  • 三、HashMap集合
  • 四、TreeSet集合
  • 五、HashSet和HashMap的區(qū)別
  • 六、HashSet和ArrayList的區(qū)別

具體內(nèi)容

一、集合框架圖

在上一篇文章中,我講解了Collection中的幾個(gè)子類,這篇文章我將主要講解Map類的幾個(gè)子類,如下圖。

部分集合框架圖

二、HashSet集合

1. 概念:
特點(diǎn):作為Set集合的一種,首先是無序的,不可重復(fù)的;允許存放null值
2. 常用方法
因?yàn)镠ashSet繼承Colletion,其實(shí)方法都大同小異,具體的代碼請(qǐng)看上一篇文章,這里再講一下removeIf方法,其他方法只列出方法名與功能。

方法名 功能
add() 添加元素
isEmpty() 如果此 set 不包含任何元素,則返回 true
contains(Object o) 判斷是否包含某個(gè)元素
int size() 獲取集合的大?。ㄋ貍€(gè)數(shù))
removeIf 根據(jù)條件刪除元素
        HashSet<String> names = new HashSet<>();
        names.add("jack");
        names.add("marry");
        names.add("abc");
        names.removeIf(ele -> ele.compareTo("c")>0);

運(yùn)行結(jié)果:[abc]
compareTo方法會(huì)用元素的首字母和指定元素的ASCII碼比較,因?yàn)?code>m,j的·ASCII碼比c的ASCII碼大,故會(huì)移除jackmarry

三、HashMap集合

1. 概念
HashMap其實(shí)就是一個(gè)有映射關(guān)系的集合。其存儲(chǔ)數(shù)據(jù)特點(diǎn)為:鍵key- 值value。比如小明語文98分,小花語文92分,小亮語文98分。人物就是key,分?jǐn)?shù)就是value,一個(gè)key只能有一個(gè)value,但是多個(gè)key可以指向同一個(gè)value。

2. 常用方法

方法名 功能
put 添加元素
size() 獲取鍵值對(duì)的個(gè)數(shù)
keySet() 獲取所有的key
values() 獲取所有的value
entrySet() 獲取Entry:key-value
get() 獲取一個(gè)鍵對(duì)應(yīng)的值

3. 簡(jiǎn)單例子
運(yùn)行結(jié)果為:
(1){English=92, Chinese=89, Math=94}
(2){English=92, Chinese=91, Math=94}
(3)3
(4)[English, Chinese, Math]
(5)[92, 91, 94]
(6)[English=92, Chinese=91, Math=94]
(7)92

```java
        HashMap<String,Integer> score = new HashMap<>();

        // 1.添加對(duì)象:鍵值對(duì)
        score.put("Chinese",89);
        score.put("Math",94);
        score.put("English",92);
        System.out.println(score);

        // 2.更改某個(gè)鍵對(duì)應(yīng)的值
        // 由于Set集合的不可重復(fù)性,再定義一個(gè)相同的key時(shí),若value不同,后者會(huì)覆蓋前者
        score.put("Chinese",91);
        System.out.println(score);

        // 3.獲取鍵值對(duì)的個(gè)數(shù)
         System.out.println(score.size());

        //4. 獲取所有的key
        System.out.println(score.keySet());

        //5. 獲取所有的value
        System.out.println(score.values());

        // 6.獲取Entry:key-value
        System.out.println(score.entrySet());

        // 7.獲取一個(gè)鍵對(duì)應(yīng)的值
        System.out.println(score.get("English"));

4. 鍵值對(duì)的遍歷方法
(1)通過遍歷key來得到每個(gè)key對(duì)應(yīng)的值,運(yùn)行結(jié)果為:
key:English value:92
key:Chinese value:91
key:Math value:94

for(String key: score.keySet()){
            //通過key得到值
            int s = score.get(key);
            System.out.println("key:"+ key+"  value:"+s);
        }

(2)通過EntrySet 得到Entry對(duì)象的集合,運(yùn)行結(jié)果為:
key:English value:92
key:Chinese value:91
key:Math value:94

// 一個(gè)Entry管理一個(gè)鍵值對(duì) getKey getValue
        Set<Map.Entry<String,Integer>> enteys = score.entrySet();
        for (Map.Entry entry:enteys){
            // 得到Entry對(duì)應(yīng)的key
            String key = (String)entry.getKey();

            // 獲取Entry對(duì)應(yīng)的值
            Integer value = (Integer)entry.getValue();

            System.out.println("key:"+ key+"  value:"+ value);
        }

四、TreeSet集合

1. 概念
TreeSet是用來排序的集合,可以實(shí)現(xiàn)對(duì)元素按照某種規(guī)則進(jìn)行排序。
2. 排序方式

(1)自然排序
TreeSet會(huì)調(diào)用集合元素的compareTo(Object obj)方法來比較元素之間大小關(guān)系,然后將集合元素按升序排列,這種方式就是自然排序。(比較的前提:兩個(gè)對(duì)象的類型相同)。

(2)比較器排序
自然排序的使用十分有限,當(dāng)我們希望一個(gè)程序能按照名字排序或者降序時(shí),則需要自定義一個(gè)比較器,即編寫一個(gè)
TreeSet默認(rèn)采用自然排序。

  • 自然排序例子
    【錯(cuò)誤版】在這個(gè)例子中,添加一個(gè)元素不會(huì)報(bào)錯(cuò),但添加兩個(gè)以上的元素后,但是沒進(jìn)行比較排序,程序會(huì)報(bào)錯(cuò),那么如何使用默認(rèn)的自然排序呢?請(qǐng)往下看。
public class Test1{
    public static void main(String[] args) {
        TreeSet<Number> ts = new TreeSet();
        Number n1 = new Number(2);
        Number n2 = new Number(1);

        //向TreeSet集合中添加兩個(gè)Number對(duì)象
        ts.add(n1);
        ts.add(n2);
        System.out.println(ts);
    }
}
class Number{
      int num;
      public Number(int num){
              this.num = num;
      }
}

【正確版】只要讓該類繼承Comparable接口就可以了,然后使用接口規(guī)定的compareTo方法。我們的輸入順序是[2,1],但是自然排序已經(jīng)按升序順序?qū)λ匦屡帕校蔬\(yùn)行結(jié)果為:[1,2]

public class Test1 {
    public static void main(String[] args) {
        TreeSet<Number> ts = new TreeSet();
        Number n1 = new Number(2);
        Number n2 = new Number(1);

        //向TreeSet集合中添加兩個(gè)Number對(duì)象
        ts.add(n1);
        ts.add(n2);
        System.out.println(ts);
    }
}
class Number implements Comparable {
    int num;
    public Number(int num){
        this.num = num;
    }

    @Override
    public int compareTo(Object o) {
        return 0;
    }
}

【進(jìn)階版】在升序排列的前提下,如果還有其他排序要求,可以重寫compareTo的方法。注意的是,數(shù)字優(yōu)先排序。下面這個(gè)例子在先按年齡升序排序,再按名字排序。運(yùn)行結(jié)果為:
[Person{name='jack', age=5}, Person{name='rose', age=18}, Person{name='rose', age=19}, Person{name='jack', age=30}]

public class Test1 {
    public static void main(String[] args) {
        TreeSet<Person> score = new TreeSet<>((Person p1,Person p2) -> p1.compareTo(p2));

        score.add(new Person("jack",5));
        score.add(new Person("jack",30));
        score.add(new Person("rose",18));
        score.add(new Person("rose",19));

        System.out.println(score);
    }
}
class Person implements Comparable{
    String name;
    int age;

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

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

    @Override
    public int compareTo(Object o) {
        // 1.判斷o對(duì)象是不是person的一個(gè)對(duì)象
        if (o instanceof Person){
            Person o1 = (Person)o;
            //自己規(guī)定比較的策略
            if (this.age != o1.age){
                return this.age - o1.age;
            }else {
                //年齡相同的情況下 再比姓名的字母
                return this.name.compareTo(o1.name);
            }
        }else {
            return -1;
        }
    }
  • 比較器排序例子
    在這個(gè)例子中,我們用比較器實(shí)現(xiàn)降序排序,可以使用Comparator接口。該接口里包含一個(gè)int compare(T o1,T o2)方法,該方法用于比較o1和o2的大小。運(yùn)行結(jié)果為:[Number{num=54}, Number{num=9}, Number{num=4}, Number{num=-3}]
public class Test1 {
    public static void main(String[] args) {
        TreeSet<Number> ts = new TreeSet<>(new Comparator<Number>() {
            @Override
            public int compare(Number num1, Number num2) {
                Number m1 = num1;
                Number m2 = num2;
                if (m1.num > m2.num) {
                    return -1;
                } else if (m1.num == m2.num) {
                    return 0;
                } else {
                    return 1;
                }
            }
        });

        ts.add(new Number(-3));
        ts.add(new Number(9));
        ts.add(new Number(54));
        ts.add(new Number(4));

        System.out.println(ts);
    }
}
class Number {
    int num;

    public Number(int num){
        this.num = num;
    }

    @Override
    public String toString() {
        return "Number{" +
                "num=" + num +
                '}';
    }
}

五、HashSet和HashMap的區(qū)別

HashMap HashSet
實(shí)現(xiàn)了Map接口 實(shí)現(xiàn)Set接口
存儲(chǔ)鍵值對(duì) 僅存儲(chǔ)對(duì)象
調(diào)用put()向map中添加元素 調(diào)用add()方法向Set中添加元素
使用鍵(Key)計(jì)算Hashcode 使用成員對(duì)象來計(jì)算hashcode值,對(duì)于兩個(gè)對(duì)象來說hashcode可能相同,所以equals()方法用來判斷對(duì)象的相等性,如果兩個(gè)對(duì)象不同的話,那么返回false
相對(duì)于HashSet較快,因?yàn)樗鞘褂梦ㄒ坏逆I獲取對(duì)象 較HashMap來說比較慢

六、HashSet和ArrayList的區(qū)別

ArrayList HashSet
元素可重復(fù) 元素不可重復(fù)
有序存放 無序存放
存儲(chǔ)數(shù)組 存儲(chǔ)對(duì)象
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 故事發(fā)生時(shí)間:2017-12-2 故事記錄時(shí)間:2017-12-3 3:03-3:15 我怎么就如此幸運(yùn)花了三個(gè)...
    李靜媛嘛嘛閱讀 179評(píng)論 0 0
  • 我對(duì)灰袍Blackwall知道的并不多。據(jù)我們了解到,在灰袍治安官Fontaine從其前任手中接下灰衛(wèi)指揮官的位置...
    Mr_Blacky閱讀 1,046評(píng)論 0 0
  • 《大蜀山下半邊街》 對(duì)大蜀山熟得很,若干年居家的郢子,距其不過五華里,大蜀山春夏秋冬盡在眼簾...
    合肥張建春閱讀 1,109評(píng)論 0 3

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