Map集合&&Map集合的不同遍歷【keySet()&&entrySet()】

Y動動發表於2020-11-07

Map集合和Collection集合的區別

Map介面下的集合與Collection介面下的集合,它們儲存資料的形式不同,如下圖。
在這裡插入圖片描述

  • Collection中的集合,元素是孤立存在的(理解為單身),向集合中儲存元素採用一個個元素的方式儲存。Map中的集合,元素是成對存在的。每個元素由鍵與值兩部分組成,通過鍵可以找對所對應的值。
  • Collection中的集合稱為單列集合,Map中的集合稱為雙列集合。需要注意的是,Map中的集合不能包含重複的鍵,值可以重複;每個鍵只能對應一個值。

Map集合特點

  • 1.Map集合是一個雙列集合,一個元素包含兩個值(一個key,一個value)
  • 2.Map集合中的元素,key和value的資料型別可以相同,也可以不同
  • 3.Map集合中的元素,key是不允許重複的,value是可以重複的
  • 4.Map集合中的元素,key和value是一一對應

注意事項:Map介面中的集合都有兩個泛型變數,在使用時,要為兩個泛型變數賦予資料型別。兩個泛型變數的資料型別可以相同,也可以不同

Map常用子類

通過檢視Map介面描述,看到Map有多個子類,這裡我們主要講解常用的HashMap集合、LinkedHashMap集合。

  • HashMap:儲存資料採用的雜湊表結構,元素的存取順序不能保證一致。由於要保證鍵的唯一、不重複,需要重寫鍵的hashCode()方法、equals()方法。
  • LinkedHashMap:HashMap下有個子類LinkedHashMap,儲存資料採用的雜湊表結構+連結串列結構。通過連結串列結構可以保證元素的存取順序一致;通過雜湊表結構可以保證的鍵的唯一、不重複,需要重寫鍵的hashCode()方法、equals()方法

HashMap集合的特點:
java.util.HashMap<k,v>集合 implements Map<k,v>介面

  • HashMap集合底層是雜湊表:查詢的速度特別的快
    JDK1.8之前:陣列+單向連結串列
    JDK1.8之後:陣列+單向連結串列|紅黑樹(連結串列的長度超過8):提高查詢的速度

  • hashMap集合是一個無序的集合,儲存元素和取出元素的順序有可能不一致

LinkedHashMap的特點:
java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合

  • LinkedHashMap集合底層是雜湊表+連結串列(保證迭代的順序)
  • LinkedHashMap集合是一個有序的集合,儲存元素和取出元素的順序是一致的。

Map介面中的常用方法

Map介面中定義了很多方法,常用的如下:

  • public V put(K key,V value):把指定的鍵與指定的值新增到Map集合中。
  • public V remove(Object key):把指定的鍵所對應的鍵值對元素在Map集合中刪除,返回被刪除元素的值。
  • public V get(Object key)根據指定的鍵,在Map集合中獲取對應的值。
  • public Set keySet():獲取Map集合中所有的【鍵】,儲存到Set集合中。
  • public Set<Map.Entry<K,V>>entrySet():獲取到Map集合中所有的鍵值對物件的【集合】(Set集合)。

【put方法】

  public V put(K key, V value):  把指定的鍵與指定的值新增到Map集合中。
   返回值:v
     儲存鍵值對的時候,key不重複,返回值V是null
    儲存鍵值對的時候,key重複,會使用新的value替換map中重複的value,返回被替換的value值

【remove方法】

  public V remove(Object key): 把指定的鍵 所對應的鍵值對元素 在Map集合中刪除,返回被刪除元素的值。
    返回值:V
       key存在,v返回被刪除的值
       key不存在,v返回null

【get方法】

  public V get(Object key) 根據指定的鍵,在Map集合中獲取對應的值。
     返回值:
        key存在,返回對應的value值
        key不存在,返回null

【containsKey方法】

boolean containsKey(Object key) 判斷集合中是否包含指定的鍵。
 包含返回true,不包含返回false

舉例實現:

package cn.itcast.day02.demo05;
import java.util.HashMap;
import java.util.Map;
public class Mapdemo {
    public static void main(String[] args) {
        //建立Map集合物件,多型
        //String-->string
        //【put方法】------Collection是【add方法】
        Map<String,String> map1=new HashMap<>();
        map1.put("鄧超","孫儷");
        map1.put("梁山伯","祝英臺");
        map1.put("傑克","露絲");
        System.out.println(map1);//{鄧超=孫儷, 傑克=露絲, 梁山伯=祝英臺}
        map1.put("傑克","魯斯");
        System.out.println("之前的傑克的露絲被覆蓋了"+map1);//{鄧超=孫儷, 傑克=魯斯, 梁山伯=祝英臺}
        //建立Map集合物件,多型
        //String-->Integer
        Map<String,Integer> map2=new HashMap<>();
        map2.put("張小花",176);
        map2.put("劉翠花",165);
        map2.put("王小菊",168);
        System.out.println(map2);
        //【remove方法】
        Integer in= map2.remove("劉翠花");
        System.out.println(in);//165
        System.out.println(map2);//{張小花=176, 王小菊=168}
        //int in2= map2.remove("劉翠花");//自動拆箱  NullPointerException
        Integer in2= map2.remove("劉翠花");//null
        System.out.println(in2);//165
        //【get方法】
 Integer in3= map2.get("張小花");//
        System.out.println(in3);//176
        Integer in4= map2.get("王小菊");
        System.out.println(in4);//168
      //【containsKey方法】
        boolean b1=map2.containsKey("張小花");
        System.out.println(b1);//true
        boolean b2=map2.containsKey("張大花");
        System.out.println(b2);//false

    }
{鄧超=孫儷, 傑克=露絲, 梁山伯=祝英臺}
之前的傑克的露絲被覆蓋了{鄧超=孫儷, 傑克=魯斯, 梁山伯=祝英臺}
{張小花=176, 王小菊=168, 劉翠花=165}
165
{張小花=176, 王小菊=168}
null
176
168
true
false

Map集合遍歷鍵找值方式【KetSet()方法】

Map集合中的方法:
Set keySet() 返回此對映中包含的鍵的 Set 檢視。
實現步驟:
1.使用Map集合中的方法【keySet()】,把Map集合所有的key取出來,儲存到一個【Set】集合中
2.遍歷set集合,獲取Map集合中的每一個key
3.通過Map集合中的方法【get(key)】,通過key找到value

package cn.itcast.day02.demo05;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapkaySetdemo {
    public static void main(String[] args) {
        Map<String,Integer> map1=new HashMap<>();
        map1.put("鄧超",111);
        map1.put("梁山伯",666);
        map1.put("傑克",444);
       Set<String> set=map1.keySet();
       //遍歷1===迭代法
      Iterator<String> it=set.iterator();
       while (it.hasNext()){
          String key=it.next();
          Integer in=map1.get(key);
          System.out.println(key+"是"+in);
       }
       //遍歷2===增強for,注意str1不是索引值,是set的內容值
        for(String str1:set)
        {
            Integer in=map1.get(str1);
            System.out.println(str1+"是"+in);
        }
        for(String str1: map1.keySet())
        {
            Integer in=map1.get(str1);
            System.out.println(str1+"是"+in);
        }

    }
}

鄧超是111
傑克是444
梁山伯是666
鄧超是111
傑克是444
梁山伯是666
鄧超是111
傑克是444
梁山伯是666

Map集合遍歷鍵值對方式【 entrySet()方法】

即通過集合中每個鍵值對(Entry)物件,獲取鍵值對(Entry)物件中的鍵與值。
Map中存放的是兩種物件,一種稱為key(鍵),一種稱為value(值),它們在在Map中是一一對應關係,這一對物件又稱做Map中的一個Entry(項)。

  • public K getKey():獲取Entry物件中的鍵。
  • public V getValue():獲取Entry物件中的值。
    在Map集合中也提供了獲取所有【Entry物件】的方法:
  • public Set<Map.Entry<K,V>> entrySet():獲取到Map集合中所有的鍵值對物件的集合(Set集合)。

實現步驟

  • 1.1.使用Map集合中的方法entrySet(),把Map集合中多個Entry物件取出來,儲存到一個Set集合中。
  • 2.遍歷Set集合,獲取每一個Entry物件
  • 3.使用Entry物件中的方法getKey()和getValue()獲取鍵與值
    注意事項
    Map集合不能直接使用迭代器或者foreach進行遍歷。但是轉成Set之後就可以使用了。
第一種情況:
HashMap儲存自定義型別鍵值
 key:Person型別
     key不可以重複(同名同年齡的人視為同一個)
     解決方法:【必須重寫hashCode方法和equals方法,可以保證key唯一】
 value:String型別
     value可以重複
 第二種情況:
  key:String型別
     String類重寫hashCode方法和equals方法,可以保證key唯一
  value:Person型別
     value可以重複(同名同年齡的人視為同一個)
package cn.itcast.day02.demo05;

import java.util.Objects;

public class Person {
    String name;
    Integer age;

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = 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 Objects.equals(name, person.name) &&
                Objects.equals(age, person.age);
    }

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

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

package cn.itcast.day02.demo05;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapPersonMain {
    public static void main(String[] args) {
        Map<Person,String> map1=new HashMap<>();
        map1.put(new Person("Y動動",2),"遼寧");
        map1.put(new Person("果果",9),"河南");
        map1.put(new Person("小豆豆",5),"山東");
        map1.put(new Person("Y動動",2),"陝西");
        System.out.println(map1);//重寫toString()
        Set<Map.Entry<Person,String>> set=map1.entrySet();
        Iterator<Map.Entry<Person,String>> it=set.iterator();
        //迭代器遍歷
        while(it.hasNext()){
            Map.Entry<Person,String> entry=it.next();
            String str=entry.getValue();
            Person p= entry.getKey();
            //System.out.println(p.getName()+p.getAge()+str);
            System.out.println(p+str);
        }
        //增強for遍歷
        for(Map.Entry<Person,String> entry:set)
        {
            Person p= entry.getKey();
            String str=entry.getValue();
            System.out.println(p+str);

        }

    }

}
{Person{name='Y動動', age=2}=陝西, Person{name='果果', age=9}=河南, Person{name='小豆豆', age=5}=山東}
____________迭代器遍歷_______________
Person{name='Y動動', age=2}陝西
Person{name='果果', age=9}河南
Person{name='小豆豆', age=5}山東
____________增強for遍歷_______________
Person{name='Y動動', age=2}陝西
Person{name='果果', age=9}河南
Person{name='小豆豆', age=5}山東

Hashmap集合和 LinkedHashMap區別

HashMap保證成對元素唯一,並且查詢速度很快,可是成對元素存放進去是沒有順序的,那麼我們要保證有序,我們需要LinkedHashMap。
java.util.LinkedHashMap<K,V> entends HashMap<K,V>
Map 介面的雜湊H表和連結列表實現,具有可預知的迭代順序。
底層原理:
雜湊表+連結串列(記錄元素的順序)

package com.itheima.demo03.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;
public class Demo01LinkedHashMap {
    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put("a","a");
        map.put("c","c");
        map.put("b","b");
        map.put("a","d");
        System.out.println(map);// key不允許重複,無序 {a=d, b=b, c=c}

        LinkedHashMap<String,String> linked = new LinkedHashMap<>();
        linked.put("a","a");
        linked.put("c","c");
        linked.put("b","b");
        linked.put("a","d");
        System.out.println(linked);// key不允許重複,有序 {a=d, c=c, b=b}
    }
}

HashTable集合

java.util.Hashtable<K,V>集合 implements Map<K,V>介面

Hashtable:底層也是一個【雜湊表】,是一個執行緒【安全】的集合,是【單執行緒】集合,速度【慢】
HashMap:底層是一個【雜湊表】,是一個執行緒【不安全】的集合,是【多執行緒】的集合,速度【快】

HashMap集合(之前學的所有的集合):可以儲存null值,null鍵
Hashtable集合,不能儲存null值,null鍵

Hashtable和Vector集合一樣,在jdk1.2版本之後被更先進的集合(HashMap,ArrayList)取代了
Hashtable的子類Properties依然活躍在歷史舞臺
Properties集合是一個唯一和IO流相結合的集合
package com.itheima.demo03.Map;
import java.util.HashMap;
import java.util.Hashtable;
public class Demo02Hashtable {
    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put(null,"a");
        map.put("b",null);
        map.put(null,null);
        System.out.println(map);//{null=null, b=null}
        Hashtable<String,String> table = new Hashtable<>();
        //table.put(null,"a");//NullPointerException
        //table.put("b",null);//NullPointerException
       // table.put(null,null);//NullPointerException
    }
}

練習【統計每個字元的個數】

練習:
計算一個字串中每個字元出現次數

分析:
    1.使用Scanner獲取使用者輸入的字串
    2.建立Map集合,key是字串中的字元,value是字元的個數
    3.遍歷字串,獲取每一個字元
    4.使用獲取到的字元,去Map集合判斷key是否存在
        key存在:
            通過字元(key),獲取value(字元個數)
            value++
            put(key,value)把新的value儲存到Map集合中
        key不存在:
            put(key,1)
    5.遍歷Map集合,輸出結果
package cn.itcast.day02.demo05;

import java.util.*;

public class MapCountmain {
    public static void main(String[] args) {
        Scanner scn=new Scanner(System.in);
        System.out.println("請輸入一個字串:");
        String str=scn.next();
        char[] c=str.toCharArray();
        Map<Character,Integer> map1=new HashMap<>();
        for (int i = 0; i < c.length; i++) {
            Character s=c[i];
           boolean bool= map1.containsKey(s);

           if(bool==true){
               Integer value=map1.get(s);
               value++;
               map1.put(s,value);

           }
           else{
               map1.put(s,1);
           }

        }
        //第一種
        Set<Character> set=map1.keySet();
        for(Character c1:set){
            Integer value=map1.get(c1);
            System.out.println(c1+"="+value);
        }
        //第二種
        Set<Map.Entry<Character,Integer>> set1=map1.entrySet();
        Iterator<Map.Entry<Character,Integer>> it=set1.iterator();
        while(it.hasNext()){
            Map.Entry<Character,Integer> entry=it.next();
          Integer value=  entry.getValue();
           Character c2= entry.getKey();
           System.out.println(c2+"="+value);
        }

    }
}

相關文章