Java_Map接口

Map接口java

1.1 Map接口概述

  咱們經過查看Map接口描述,發現Map接口下的集合與Collection接口下的集合,它們存儲數據的形式不一樣,以下圖。數組

  • Collection中的集合,元素是孤立存在的(理解爲單身),向集合中存儲元素採用一個個元素的方式存儲。
  • Map中的集合,元素是成對存在的(理解爲夫妻)。每一個元素由鍵與值兩部分組成,經過鍵能夠找對所對應的值。
  • Collection中的集合稱爲單列集合,Map中的集合稱爲雙列集合。
  • 須要注意的是,Map中的集合不能包含重複的鍵,值能夠重複;每一個鍵只能對應一個值。
  • Map中經常使用的集合爲HashMap集合、LinkedHashMap集合。

1.2 Map接口中經常使用集合概述

經過查看Map接口描述,看到Map有多個子類,這裏咱們主要講解經常使用的HashMap集合、LinkedHashMap集合。ide

  • HashMap<K,V>:存儲數據採用的哈希表結構,元素的存取順序不能保證一致。因爲要保證鍵的惟1、不重複,須要重寫鍵的hashCode()方法、equals()方法。
  • LinkedHashMap<K,V>:HashMap下有個子類LinkedHashMap,存儲數據採用的哈希表結構+鏈表結構。經過鏈表結構能夠保證元素的存取順序一致;經過哈希表結構能夠保證的鍵的惟1、不重複,須要重寫鍵的hashCode()方法、equals()方法。
  • 注意:Map接口中的集合都有兩個泛型變量<K,V>,在使用時,要爲兩個泛型變量賦予數據類型。兩個泛型變量<K,V>的數據類型能夠相同,也能夠不一樣。

 

1.3 Map接口中的經常使用方法

  • put方法:將指定的鍵與值對應起來,並添加到集合中
    • 方法返回值爲鍵所對應的值

    使用put方法時,若指定的鍵(key)在集合中沒有,則沒有這個鍵對應的值,返回null,並把指定的鍵值添加到集合中; 工具

    使用put方法時,若指定的鍵(key)在集合中存在,則返回值爲集合中鍵對應的值(該值爲替換前的值),並把指定鍵所對應的值,替換成指定的新值。測試

  • get方法:獲取指定鍵(key)所對應的值(value)
  • remove方法:根據指定的鍵(key)刪除元素,返回被刪除元素的值(value)。

Map接口的方法演示this

public class MapDemo {
    public static void main(String[] args) {
        //建立Map對象
        Map<String, String> map = new HashMap<String,String>();
        //給map中添加元素
        map.put("星期一", "Monday");
        map.put("星期日", "Sunday");
        System.out.println(map); // {星期日=Sunday, 星期一=Monday}

        //當給Map中添加元素,會返回key對應的原來的value值,若key沒有對應的值,返回null
        System.out.println(map.put("星期一", "Mon")); // Monday
        System.out.println(map); // {星期日=Sunday, 星期一=Mon}

        //根據指定的key獲取對應的value
        String en = map.get("星期日");
        System.out.println(en); // Sunday
        
        //根據key刪除元素,會返回key對應的value值
        String value = map.remove("星期日");
        System.out.println(value); // Sunday
        System.out.println(map); // {星期一=Mon}
    }
}
View Code

 

1.4 Map集合遍歷鍵找值方式

鍵找值方式:即經過元素中的鍵,獲取鍵所對應的值編碼

操做步驟與圖解:spa

 1.獲取Map集合中全部的鍵,因爲鍵是惟一的,因此返回一個Set集合存儲全部的鍵設計

2.遍歷鍵的Set集合,獲得每個鍵3d

3.根據鍵,獲取鍵所對應的值

代碼演示:

publicclass MapDemo {

    publicstaticvoid main(String[] args) {

        //建立Map對象

        Map<String, String> map = new HashMap<String,String>();

        //給map中添加元素

        map.put("鄧超", "孫儷");

        map.put("李晨", "范冰冰");

map.put("劉德華", "柳巖");

        //獲取Map中的全部key

        Set<String> keySet = map.keySet();

        //遍歷存放全部key的Set集合

        Iterator<String> it =keySet.iterator();

        while(it.hasNext()){

            //獲得每個key

            String key = it.next();

            //經過key獲取對應的value

            String value = map.get(key);

            System.out.println(key+"="+value);

        }

    }

}
View Code

1.5 Entry鍵值對對象

在Map類設計時,提供了一個嵌套接口:Entry。Entry將鍵值對的對應關係封裝成了對象。即鍵值對對象,這樣咱們在遍歷Map集合時,就能夠從每個鍵值對(Entry)對象中獲取對應的鍵與對應的值。

  • Entry是Map接口中提供的一個靜態內部嵌套接口。
  • getKey()方法:獲取Entry對象中的鍵
  • getValue()方法:獲取Entry對象中的值
  • entrySet()方法:用於返回Map集合中全部的鍵值對(Entry)對象,以Set集合形式返回。

1.6 Map集合遍歷鍵值對方式

鍵值對方式:即經過集合中每一個鍵值對(Entry)對象,獲取鍵值對(Entry)對象中的鍵與值。

操做步驟與圖解:

    1.獲取Map集合中,全部的鍵值對(Entry)對象,以Set集合形式返回。

    2.遍歷包含鍵值對(Entry)對象的Set集合,獲得每個鍵值對(Entry)對象

    3.經過鍵值對(Entry)對象,獲取Entry對象中的鍵與值。

 

publicclass MapDemo {

    publicstaticvoid main(String[] args) {

        //建立Map對象

        Map<String, String> map = new HashMap<String,String>();

        //給map中添加元素

        map.put("鄧超", "孫儷");

        map.put("李晨", "范冰冰");

map.put("劉德華", "柳巖");

        //獲取Map中的全部key與value的對應關係

        Set<Map.Entry<String,String>> entrySet = map.entrySet();

        //遍歷Set集合

        Iterator<Map.Entry<String,String>> it =entrySet.iterator();

        while(it.hasNext()){

            //獲得每一對對應關係

            Map.Entry<String,String> entry = it.next();

            //經過每一對對應關係獲取對應的key

            String key = entry.getKey();

            //經過每一對對應關係獲取對應的value

            String value = entry.getValue();

            System.out.println(key+"="+value);

        }

    }

}
View Code

注意:Map集合不能直接使用迭代器或者foreach進行遍歷。可是轉成Set以後就可使用了。

 

1.7 HashMap存儲自定義類型鍵值

 

練習:每位學生(姓名,年齡)都有本身的家庭住址。那麼,既然有對應關係,則將學生對象和家庭住址存儲到map集合中。學生做爲鍵, 家庭住址做爲值。

注意,學生姓名相同而且年齡相同視爲同一名學生。

  • 學生類
publicclass Student {

    private String name;

    privateint age;

 

    //編寫構造方法,文檔中已省略

    //編寫get,set方法,文檔中已省略

    //編寫toString方法,文檔中已省略

}
View Code
  • 測試類
public class HashMapTest {

    public static void main(String[] args) {

        //1,建立hashmap集合對象。

        Map<Student,String> map = new HashMap<Student,String>();

        

        //2,添加元素。

        map.put(new Student("lisi",28), "上海");

        map.put(new Student("wangwu",22), "北京");

        map.put(new Student("zhaoliu",24), "成都");

        map.put(new Student("zhouqi",25), "廣州");

        map.put(new Student("wangwu",22), "南京");

        

        //3,取出元素。鍵找值方式

        Set<Student> keySet = map.keySet();

        for(Student key : keySet){

            String value = map.get(key);

            System.out.println(key.toString()+"....."+value);

        }

        

        //取出元素。鍵值對方式

        Set<Map.Entry<Student, String>> entrySet = map.entrySet();

        for (Map.Entry<Student, String> entry : entrySet) {

            Student key = entry.getKey();

            String value = entry.getValue();

            System.out.println(key.toString()+"....."+value);

        }

    }

}
View Code
  • 當給HashMap中存放自定義對象時,若是自定義對象做爲key存在,這時要保證對象惟一,必須複寫對象的hashCode和equals方法(若是忘記,請回顧HashSet存放自定義對象)。
  • 若是要保證map中存放的key和取出的順序一致,可使用LinkedHashMap集合來存放。

 

1.8 靜態導入

 

在導包的過程當中咱們能夠直接導入靜態部分,這樣某個類的靜態成員就能夠直接使用了。在源碼中常常會出現靜態導入。

靜態導入格式:

import static XXX.YYY; 導入後YYY可直接使用。

    

例如:Map.Entry的訪問,簡化後爲Entry

import static java.util.Map.Entry;

public class HashMapTest {

    public static void main(String[] args) {

        //1,建立hashmap集合對象。

        Map<Student,String> map = new HashMap<Student,String>();

 

        //取出元素。鍵值對方式

        //Set<Map.Entry<Student, String>> entrySet = map.entrySet();

        Set<Entry<Student, String>> entrySet = map.entrySet();

 

        //for (Map.Entry<Student, String> entry : entrySet) {

        for (Entry<Student, String> entry : entrySet) {

            Student key = entry.getKey();

            String value = entry.getValue();

            System.out.println(key.toString()+"....."+value);

        }

    }

}
View Code

 

1.9 可變參數

在JDK1.5以後,若是咱們定義一個方法須要接受多個參數,而且多個參數類型一致,咱們能夠對其簡化成以下格式:

修飾符返回值類型方法名(參數類型... 形參名){ }

其實這個書寫徹底等價與

修飾符返回值類型方法名(參數類型[] 形參名){ }

只是後面這種定義,在調用時必須傳遞數組,而前者能夠直接傳遞數據便可。

 

jdk1.5之後。出現了簡化操做。... 用在參數上,稱之爲可變參數。

一樣是表明數組,可是在調用這個帶有可變參數的方法時,不用建立數組(這就是簡單之處),直接將數組中的元素做爲實際參數進行傳遞,其實編譯成的class文件,將這些元素先封裝到一個數組中,在進行傳遞。這些動做都在編譯.class文件時,自動完成了。

代碼演示:

public class ParamDemo {

    public static void main(String[] args) {

        int[] arr = {21,89,32};

        int sum = add(arr);

        System.out.println(sum);

        sum = add(21,89,32);//可變參數調用形式

        System.out.println(sum);

        

    }

 

    //JDK1.5以後寫法

    public static int add(int...arr){

        int sum = 0;

        for (int i = 0; i < arr.length; i++) {

            sum += arr[i];

        }

        return sum;

    }

 

    //原始寫法

    /*

    public static int add(int[] arr) {

        int sum = 0;

        for (int i = 0; i < arr.length; i++) {

            sum += arr[i];

        }

        return sum;

    }

    */

}
View Code
  • 上述add方法在同一個類中,只能存在一個。由於會發生調用的不肯定性

注意:若是在方法書寫時,這個方法擁有多參數,參數中包含可變參數,可變參數必定要寫在參數列表的末尾位置。

 

1.10 Collections集合工具類

 

Collections是集合工具類,用來對集合進行操做。部分方法以下:

  • public static <T> void sort(List<T> list) // 集合元素排序
//排序前元素list集合元素 [33,11,77,55]

Collections.sort( list );

//排序後元素list集合元素 [11,33,55,77]
  • public static void shuffle(List<?> list) // 集合元素存儲位置打亂
//list集合元素 [11,33,55,77]

Collections.shuffle( list );

//使用shuffle方法後,集合中的元素爲[77,33,11,55],每次執行該方法,集合中存儲的元素位置都會隨機打亂

1.11 集合嵌套

集合嵌套並非一個新的知識點,僅僅是集合內容又是集合,如Collection集合嵌套、Collection集合與Map集合相互嵌套、Map集合嵌套。

  • ArrayList嵌套 ArrayList

        ArrayList< ArrayList<String> >

        Collection< ArrayList<Integer> >

  • Map嵌套 ArrayList

      HashMap<String, ArrayList<Person>>

      ArrayList< HashMap<String, String>>

  • Map集合嵌套

      HashMap<String, HashMap<String,String>>

      HashMap<String, HashMap<Person,String>>

1.12 集合繼承體系的面向對象思想

 

  • 接口:用來明確全部集合中該具備的功能,至關於在定義集合功能標準;
  • 抽象類:把多個集合中功能實現方式相同的方法,抽取到抽象類實現,具體集合再也不遍寫,繼承使用便可;
  • 具體類:繼承抽象類,實現接口,重寫全部抽象方法,達到具有指定功能的集合。每一個具體集合類,根據自身的數據存儲結構方式,對接口中的功能方法,進行不一樣方式的實現。
  •  

模擬鬥地主洗牌發牌

1 案例介紹

按照鬥地主的規則,完成洗牌發牌的動做。

 

具體規則:

    1. 組裝54張撲克牌

 2. 將54張牌順序打亂

    3. 三個玩家參與遊戲,三人交替摸牌,每人17張牌,最後三張留做底牌。

    4. 查看三人各自手中的牌(按照牌的大小排序)、底牌

  • 手中撲克牌從大到小的擺放順序:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3

 

2 案例需求分析

 

  • 準備牌:

    完成數字與紙牌的映射關係:

        使用雙列Map(HashMap)集合,完成一個數字與字符串紙牌的對應關係(至關於一個字典)。

  • 洗牌:

    經過數字完成洗牌發牌

  • 發牌:

    將每一個人以及底牌設計爲ArrayList<String>,將最後3張牌直接存放於底牌,剩餘牌經過對3取模依次發牌。

存放的過程當中要求數字大小與鬥地主規則的大小對應。

  將表明不一樣紙牌的數字分配給不一樣的玩家與底牌。

  • 看牌:

      經過Map集合找到對應字符展現。

    經過查詢紙牌與數字的對應關係,由數字轉成紙牌字符串再進行展現。

  1. 實現代碼步驟

首先,要修改java文件編碼,由GBK修改成UTF-8,由於默認的字符編碼GBK沒有咱們要的梅花、方片、黑桃、紅桃(♠♥♦♣)等特殊字符。

 

import java.util.ArrayList;

import java.util.Collections;

import java.util.HashMap;

 

/*

* 鬥地主洗牌發牌排序

*/

public class Poker {

 

    public static void main(String[] args) {

 

        //準備花色

        ArrayList<String> color = new ArrayList<String>();

        color.add("♠");

        color.add("♥");

        color.add("♦");

        color.add("♣");

        

        //準備數字

        ArrayList<String> number = new ArrayList<String>();

Collections.addAll(number,"3","4","5","6","7","8","9","10","J","Q","K","A","2");

        

        //定義一個map集合:用來將數字與每一張牌進行對應

        HashMap<Integer, String> map = new HashMap<Integer, String>();

        

        int index = 0;

        for (String thisNumber : number) {

            for (String thisColor : color) {

                map.put(index++, thisColor+thisNumber);

            }

        }

        

        //加入大小王

        map.put(index++, "小☺");

        map.put(index++, "大☻");

        

        //一副54張的牌 ArrayList裏邊爲0-53的數的新牌

        ArrayList<Integer> cards = new ArrayList<Integer>();

        

        for (int i = 0; i <= 53; i++) {

            cards.add(i);

        }

        

        //洗牌

        Collections.shuffle(cards);

        

        //建立三個玩家和底牌

        ArrayList<Integer> iPlayer = new ArrayList<Integer>();

        ArrayList<Integer> iPlayer2 = new ArrayList<Integer>();

        ArrayList<Integer> iPlayer3 = new ArrayList<Integer>();

        ArrayList<Integer> itCards = new ArrayList<Integer>();

        

        //遍歷這副洗好的牌,遍歷過程當中,將牌發到三個玩家和底牌中

        for (int i = 0; i < cards.size(); i++) {

            if(i>=51) {

                iCards.add(cards.get(i));

            } else {

                if(i%3==0) {

                    iPlayer.add(cards.get(i));

                }else if(i%3==1) {

                    iPlayer2.add(cards.get(i));

                }else {

                    iPlayer3.add(cards.get(i));

                }

            }

        }

        

        //對每一個人手中的牌排序

        Collections.sort(iPlayer);

        Collections.sort(iPlayer2);

        Collections.sort(iPlayer3);

        

        //對應數字形式的每一個人手中的牌,定義字符串形式的牌

        ArrayList<String> sPlayer = new ArrayList<String>();

        ArrayList<String> sPlayer2 = new ArrayList<String>();

        ArrayList<String> sPlayer3 = new ArrayList<String>();

        ArrayList<String> sCards = new ArrayList<String>();

        

        for (Integer key : iPlayer) {

            sPlayer.add(map.get(key));

        }

        for (Integer key : iPlayer2) {

            sPlayer2.add(map.get(key));

        }

        for (Integer key : iPlayer3) {

            sPlayer3.add(map.get(key));

        }

        for (Integer key : iCards) {

            sCards.add(map.get(key));

        }

        

        //看牌

        System.out.println(sPlayer);

        System.out.println(sPlayer2);

        System.out.println(sPlayer3);

        System.out.println(sCards);

    }

}
View Code

 

總結

知識點總結

  • Map集合:

            map集合中的元素都是成對出現,成對存儲的

            map集合中的元素都是以一對鍵和值的形式組成存在的,稱爲鍵值對,理解爲夫妻對

            map集合中的鍵不能重複存儲,值能夠重複

            map集合中的每個鍵 對應着一個值

  • 方法:

      V put(K key, V value) 把指定的鍵與指定的值添加到Map集合中

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

  Set<Map.Entry<K,V>> entrySet() 獲取到Map集合中全部的鍵值對對象的集合(Set集合)

  V get(Object key) 根據指定的鍵,在Map集合中獲取對應的值

  Set<K> keySet() 獲取Map集合中全部的鍵,存儲到Set集合中

 

  • Map集合遍歷的兩種方式
    • 方式1:根據鍵找值的方式 
 //a, 獲取到Map集合中全部的鍵,返回對應的Set集合

        //b, 遍歷鍵的集合,獲取到每個鍵

        //c, 經過鍵,找到對應的值

        

        //獲取到Map集合中全部的鍵,返回對應的Set集合

        Set<String> keys = map.keySet();

        //遍歷鍵的集合,獲取到每個鍵

        for (String key : keys) {

            //經過鍵,找到對應的值

            Student s = map.get(key);

            System.out.println( key + "..." + s.getName() + "..." + s.getAge() );

        }
View Code
  • 方式2:根據鍵值對對象找鍵和值的方式

 

//a, 獲取Map集合中全部的鍵值對元素,返回對應的Set集合

        //b, 遍歷鍵值對元素集合,獲取到每個鍵值對元素對象

        //c, 經過鍵值對元素對象,獲取對應的鍵,和對應的值

        

        //獲取Map集合中全部的鍵值對元素,返回對應的Set集合

        Set< Map.Entry<String, Student>> entrySet = map.entrySet();

        //遍歷鍵值對元素集合,獲取到每個鍵值對元素對象

        for (Map.Entry<String, Student> entry : entrySet) {

            //經過鍵值對元素對象,獲取對應的鍵,和對應的值

            //找鍵

            String key = entry.getKey();

            //找值

            Student s = entry.getValue();

            //打印

            System.out.println( key+"..."+s.getName()+"..."+s.getAge() );

        }
View Code
  • HashMap:
    • 特色:

            是Map集合的子集合

            底層採用哈希表結構

            HashMap集合中的key不能重複,經過重寫hashCode() 與 equals()方法來保證鍵的惟一。

            不能保證元素存與取的順序徹底一致

  • LinkedHashMap:
    • 特色:

    是HashMap集合的子集合

    底層採用哈希表+鏈表結構

    LinkedHashMap集合中的key不能重複,經過重寫hashCode() 與 equals()方法來保證鍵的惟一。

 

  • Collections中的方法:

            public static <T> void sort(List<T> list) 排序

           public static void shuffle(List<?> list) 集合中的元素存儲位置隨機打亂

相關文章
相關標籤/搜索