Java基礎集合篇03-Map集合

1. Map集合

1.1 Map集合介紹

  • Map集合是一個存儲數據的容器。
  • Map集合存儲數據的方式是鍵值對(key/value)。
    • key鍵不能夠重複(若重複設置,則會覆蓋原有key對應的值)。
    • value值能夠重複。
  • Map集合的底層數據結構是哈希表(數組+鏈表/紅黑樹)。

1.2 Map集合和Collection集合區別

  • Collection集合是單例集合
    • 元素的種類是單個
  • Map集合是雙例集合。
    • 元素的種類是一對
  • 圖解:java


     
    單例集合和雙例集合

1.3 Map集合經常使用子類

  • HasMap
    • 是Map集合的一個子類
    • 底層數據結構是哈希表
    • 鍵不能夠重複(鍵對應的類型須要重寫了hashCode()和equals方法()),值能夠重複。
    • 存取是無序的(存取順序可能不一致)
  • LinkedHashMap
    • 是HashMap集合的一個子類
    • 底層數據結構是哈希表+鏈表(記錄存取順序)
    • 鍵不能夠重複(鍵對應的類型須要重寫了hashCode()和equals方法()),值能夠重複。
    • 存取是有序的(存取的順序必定是一致的)

注意事項:Map接口中的集合都有兩個泛型變量,在使用時,要爲兩個泛型變量賦予數據類型。兩個泛型變量的數 據類型能夠相同,也能夠不一樣。數組

1.4 Map接口中經常使用方法

  • 方法安全

    public V put(K key, V value) : 把指定的鍵與指定的值添加到Map集合中。數據結構

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

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

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

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

  • 代碼spa

    // 建立HashMap對象 HashMap<String,String> hash = new HashMap<>(); // 【添加數據-public V put(K key, V value)】 hash.put("郭靖","華箏"); hash.put("郭靖","黃蓉"); // 會覆蓋以前重複的鍵值對 hash.put("楊過","小龍女"); hash.put("張無忌","趙敏"); hash.put("宋青書","周芷若"); System.out.println(hash); // {楊過=小龍女, 宋青書=周芷若, 郭靖=黃蓉, 張無忌=趙敏} // 【移除數據-public V remove(Object key)】 hash.remove("宋青書"); System.out.println(hash); // {楊過=小龍女, 郭靖=黃蓉, 張無忌=趙敏} // 【根據指定的鍵獲取對應的值-public V get(Object key)】 String value = hash.get("郭靖"); System.out.println(value); // 黃蓉 // 【獲取Map集合中全部的鍵存儲到Set集合中-public Set<K> keySet()】 Set<String> set = hash.keySet(); Iterator<String> iterator = set.iterator(); while ((iterator.hasNext())){ String key = iterator.next(); System.out.println(key + "-" + hash.get(key)); } // 【獲取Map集合中的Entry對象-public Set<Map.Entry<K,V>> entrySet()】 // Map集合中存儲了一組Entry對象,entry對象包裝了每一對key/value // Entry對象能夠經過getKey()方法獲取鍵,經過getValue方法獲取對應的值 Set<Map.Entry<String,String>> set2 = hash.entrySet(); for (Map.Entry<String,String> entry:set2) { System.out.println(entry.getKey() + '|'+entry.getValue()); }

1.5 Map集合中定義自定義類型的鍵值對

  • 注意事項:對應自定義類型的鍵的類型中須要從新hashCode和equals方法線程

  • 代碼:

    //【執行類】 public class Main { public static void main(String[] args) { // 存儲一組學生信息,要求集合中不容許出現同名同年齡的鍵 HashMap<Student,Integer> hash = new HashMap<>(); hash.put(new Student("張三",18),10010); hash.put(new Student("張三",18),10086); hash.put(new Student("李四",17),10010); hash.put(new Student("王五",17),10010); System.out.println(hash.size()); // 3個 } } //【學生類】 public class Student { 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 boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && name.equals(student.name); } @Override public int hashCode() { return Objects.hash(name, age); } }

1.6 LinkedHashMap

  • 介紹:是HashMap的子類,存取數據是有序的。

  • 代碼:

    LinkedHashMap<String,String> hash = new LinkedHashMap<>(); hash.put("郭靖","黃蓉"); hash.put("楊過","小龍女"); hash.put("張無忌","趙敏"); hash.put("宋青書","周芷若"); System.out.println(hash);//{郭靖=黃蓉, 楊過=小龍女, 張無忌=趙敏, 宋青書=周芷若}

1.7 Map集合練習

  • 需求:計算一個字符串中每一個字符出現次數。

  • 業務分析:

    • 接受用戶輸入的內容
    • 提取每個字符並統計次數
    • 打印統計結果
  • 代碼:

    // 1. 接受用戶輸入的內容 String text = new Scanner(System.in).next(); // 2. 建立Map集合key存儲字符,value存儲次數 LinkedHashMap<Character,Integer> hash = new LinkedHashMap<>(); // 3. 循環遍歷字符串中的字符,並統計 for(int i = 0; i < text.length();i++) { // 3.1 取出單個字符 char ch = text.charAt(i); // 3.2 檢測集合中是否存在這樣的鍵 boolean isHas = hash.containsKey(ch); // 3.3 若存在,則設置key的值次數加1 if(isHas) { int count = hash.get(ch) + 1; hash.put(ch,count); }else {// 不然,則向集合中添加key並設置次數爲1 hash.put(ch,1); } } // 4.遍歷並打印 // 4.1 獲取集合中的鍵 Set<Character> set = hash.keySet(); // 4.2 遍歷 for(Character ch:set){ System.out.println(ch+":" + hash.get(ch)); }

1.8 JDK9對集合添加的優化

  • 在建立少許元素的集合時,使用JDK9中提供的靜態方法of添加更加合適

  • 注意事項:

    • of方法只能被接口List、Set、Map接口調用,不能用子類或實現類調用。
    • of方法初始化後的集合不能更改。
  • 代碼:

    List<String> list = List.of("張三","李四","王五","趙六"); Set<String> set = Set.of("張三","李四","王五","趙六"); Map<String,Integer> map = Map.of("張三",10,"李四",12); System.out.println(list); // [張三, 李四, 王五, 趙六] System.out.println(set); // [李四, 趙六, 張三, 王五] System.out.println(map); // {張三=10, 李四=12}

1.9 HashTable

  • HashTable集合

    • 底層是線程是安全的,單線程,執行速度慢
    • 底層數據結構是哈希表
    • 以前學習的集合能夠存儲null鍵和null值,可是HashTable不能夠
  • 代碼:

    HashMap<String,Integer> map = new HashMap<>(); map.put(null,1); map.put("a",null); System.out.println(map); Hashtable<String,Integer> table = new Hashtable<>(); table.put(null,1); // 報錯NullPointerException table.put("a",null); System.out.println(table);

2. 模擬鬥地主洗牌發牌

  • 需求:

    • 實現洗牌、發牌、看片、玩家牌排序(從小到大)的功能
  • 代碼:

    public static void main(String[] args) { // 1. 定義Map集合用來裝牌 HashMap<Integer,String> map = new HashMap<>(); // 2. 定義數組存放花色 String[]colors={"♥","♠","♣","♦"}; // 3. 定義數組存放牌數字 String[]nums = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"}; // 4. 定義List集合存放牌的索引 ArrayList<Integer> listIndex = new ArrayList<>(); // 5. 定義初始化牌的索引爲0 int index = 0; // 添加大小王 map.put(index,"大王"); listIndex.add(index); index++; map.put(index,"小王"); listIndex.add(index); index++; // 6. 組裝牌 for (int i = 0; i < nums.length; i++) { for (int i1 = 0; i1 < colors.length; i1++) { listIndex.add(index); map.put( index,colors[i1]+nums[i]); index++; } } // 7.洗牌 Collections.shuffle(listIndex); // 8. 定義玩家牌和底牌集合 ArrayList<Integer> player01ListIndex = new ArrayList<>(); ArrayList<Integer> player02ListIndex = new ArrayList<>(); ArrayList<Integer> player03ListIndex = new ArrayList<>(); ArrayList<Integer> diPai3ListIndex = new ArrayList<>(); // 9. 發牌 for (int i = 0; i < listIndex.size(); i++) { if(i>=51) { diPai3ListIndex.add(listIndex.get(i)); }else if(i%3==0) { player01ListIndex.add(listIndex.get(i)); }else if(i%3==1) { player02ListIndex.add(listIndex.get(i)); }else if(i%3==2) { player03ListIndex.add(listIndex.get(i)); } } // 10. 看牌 show(map,player01ListIndex,"周星馳"); show(map,player02ListIndex,"劉德華"); show(map,player03ListIndex,"周潤發"); show(map,diPai3ListIndex,"底牌"); } // 看牌方法 public static void show(HashMap<Integer,String> map,ArrayList<Integer> listIndex,String name){ System.out.println("================【"+name+"】==================="); Collections.sort(listIndex); for (int i = 0; i < listIndex.size(); i++) { int key = listIndex.get(i); System.out.print("【"+map.get(key)+"】"); } System.out.println(""); }
相關文章
相關標籤/搜索