day13【學生管理系統、Map、集合的嵌套】 課上

1.學生管理系統(課下完成)

1.1修改

 //修改
    private static void updateStudent(ArrayList<Student> list) {
        //創建鍵盤錄入的對象
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入要修改的學員的編號:");
        //獲取錄入的學員編號
        int input_id = sc.nextInt();
        //遍歷list集合
        for (int i = 0; i < list.size(); i++) {
            //取出每個學生
            Student s = list.get(i);
            //獲取學生編號
            int list_id = s.getId();
            //判斷錄入的編號和集合中取出的學生編號是否相等
            if(input_id == list_id){
                //說明找到了
                //錄入學員新的信息並修改
                System.out.println("請輸入新的學員姓名:(保留原值請輸入0)");
                String name = sc.next();

                System.out.println("請輸入新的學員性別:(保留原值請輸入0)");
                String sex = sc.next();

                System.out.println("請輸入新的學員生日:(保留原值請輸入0)");
                String birthday = sc.next();
                //上述如果在控制檯輸入0屬於字符串 "0"
                //判斷是否修改姓名
                if(!"0".equals(name)){
                    //說明希望修改
                    s.setName(name);
                }

                //判斷是否修改性別
                if(!"0".equals(sex)){
                    //說明希望修改
                    s.setSex(sex);
                }

                //判斷是否修改生日
                if(!"0".equals(birthday)){
                    //說明希望修改
                    //修改生日
                    s.setBirthday(birthday);
                    //將新的生日傳入到工具類中計算新的年齡
                    int age = Utils.birthdayToAge(birthday);//新的年齡
                    s.setAge(age);
                }
                System.out.println("【修改成功】");
                //停止方法 updateStudent
                return;
            }
        }
        //如果能夠執行到這裏,說明沒有執行上述for循環中的if語句,因爲if語句如果執行完畢最後有一個return直接結束方法了
        //也就是說沒有找到和錄入的學號相等的學號
        System.out.println("【你輸入的編號不存在】");
    }

1.2刪除

 //刪除學生
    private static void deleteStudent(ArrayList<Student> list) {
        //創建鍵盤錄入的對象
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入要刪除的學員的編號:");
        //錄入的學員編號
        int input_id = sc.nextInt();
        /*
            這裏不會報併發修改異常,因爲只有使用迭代器Iterator或者增強for循環的時候纔會報併發修改異常
            併發修改異常位於內部類Itr類中
            這裏和迭代器沒有關係,所以不會報併發修改異常
         */
        //遍歷集合
        for (int i = 0; i < list.size(); i++) {
            //取出學生對象
            Student s = list.get(i);
            //獲取集合中的學生編號
            int list_id = s.getId();
            //判斷鍵盤錄入的學生編號和集合中的學生編號是否一致
            if(input_id == list_id){
                //說明找到了學生,直接從集合中刪除
                list.remove(i);//根據索引刪除
                System.out.println("【刪除成功】");
                //結束方法
                return;
            }
        }
        //如果能夠執行到這裏說明沒有找到學員
        System.out.println("【您輸入的編號有誤】");
    }

2.Map集合介紹(掌握)

1.Map<K,V> 屬於雙列集合,每次可以添加一對數據,並且這兩個數據具有映射關係。

舉例:人和身份證 、身份證和駕駛證、老公和老婆等。都可以使用雙列集合Map存儲。

2.雙列集合Map的第一個泛型:K是key的簡寫 表示鍵 ,V 是value的簡寫表示值,整體稱爲鍵值對

3.單列集合和雙列集合區別

在這裏插入圖片描述

3.Map的繼承體系(理解)

在這裏插入圖片描述

  • HashMap<K,V>:存儲數據採用的哈希表結構,元素的存取順序不能保證一致。由於要保證鍵的唯一、不重複,需要重寫的hashCode()方法、equals()方法。哈希表控制鍵,鍵唯一。
  • LinkedHashMap<K,V>:HashMap下有個子類LinkedHashMap,存儲數據採用的哈希表結構+鏈表結構。通過鏈表結構可以保證元素的存取順序一致;通過哈希表結構可以保證的鍵的唯一、不重複,需要重寫鍵的hashCode()方法、equals()方法。
  • TreeMap<K,V>:TreeMap集合和Map相比沒有特有的功能,底層的數據結構是紅黑樹;可以對元素的**進行排序,排序方式有兩種:自然排序比較器排序
  • Hashtable被HashMap集合取代了 安全的,但是效率比HashMap低
  • ConcurrentHashMap屬於多線程安全,效率低 比Hashtable效率高

tips:Map接口中的集合都有兩個泛型變量<K,V>,在使用時,要爲兩個泛型變量賦予數據類型。兩個泛型變量<K,V>的數據類型可以相同,也可以不同。

4.Map接口的方法介紹(掌握)

package com.itheima.sh.map_method_01;

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

/*
    Map接口中定義了很多方法,常用的如下:
    1.public V put(K key, V value)`:  把指定的鍵與指定的值添加到Map集合中。
        說明:
            1)執行put添加數據的時候,如果新添加的鍵不存在,那麼此時直接添加,並返回null
            2)執行put添加數據的時候,如果新添加的鍵存在,那麼新添加的value覆蓋之前舊的value,並返回舊的value
    2.public V remove(Object key)`: 把指定的鍵 所對應的鍵值對元素 在Map集合中刪除,返回被刪除元素的值。
    3.public V get(Object key)` 根據指定的鍵,在Map集合中獲取對應的值。
    4.public Set<K> keySet()`: 獲取Map集合中所有的鍵,存儲到Set集合中。
    5.public Set<Map.Entry<K,V>> entrySet()`: 獲取到Map集合中所有的鍵值對對象的集合(Set集合)。
            說明:該方法表示獲取Map集合中的所有的鍵值對,存放到單列集合Set中,鍵值對屬於Map.Entry<K,V>類型
    6.public boolean containKey(Object key)`:判斷該集合中是否有此鍵。 如果包含返回true,否則返回false
    7. int size() 返回此映射中的鍵-值映射關係數。 集合長度
 */
public class MapDemo01 {
    public static void main(String[] args) {
        method_2();

    }

    private static void method_2() {
        Map<String, String> map = new HashMap<>();
        //添加數據
        map.put("黃曉明", "baby");
        map.put("謝霆鋒", "王菲");
        map.put("汪峯", "章子怡");
        map.put("鄧超", "孫儷");
        map.put("柳巖", "baby");
        // 2.public V remove(Object key)`: 把指定的鍵 所對應的鍵值對元素 在Map集合中刪除,返回被刪除元素的值。
//        String value = map.remove("柳巖");
//        System.out.println("value = " + value);
//        System.out.println("map = " + map);//map = {鄧超=孫儷, 謝霆鋒=王菲, 汪峯=章子怡, 黃曉明=baby}
//
//
//        //3.public V get(Object key)` 根據指定的鍵,在Map集合中獲取對應的值。
//        //需求:根據謝霆鋒獲取值value
//        String value2 = map.get("謝霆鋒");
//        System.out.println("value2 = " + value2);//王菲


        //4.public Set<K> keySet()`: 獲取Map集合中所有的鍵,存儲到Set集合中。
        Set<String> keys = map.keySet();
        System.out.println("keys = " + keys);


        //5.public Set<Map.Entry<K,V>> entrySet()`: 獲取到Map集合中所有的鍵值對對象的集合(Set集合)。
        Set<Map.Entry<String, String>> entries = map.entrySet();
        //entries = [鄧超=孫儷, 謝霆鋒=王菲, 柳巖=baby, 汪峯=章子怡, 黃曉明=baby]
        System.out.println("entries = " + entries);


        //6.public boolean containKey(Object key)`:判斷該集合中是否有此鍵。 如果包含返回true,否則返回false
        //需求判斷是否包含 汪峯

        boolean boo = map.containsKey("汪峯");
        System.out.println("boo = " + boo);//boo = true


        //7. int size() 返回此映射中的鍵-值映射關係數。 集合長度
        System.out.println(map.size());


        // void putAll(Map<? extends K,? extends V> m) 將參數的map集合放到調用的map集合中
        //創建空的map集合
        Map<String, String> map2 = new HashMap<>();
        //將map集合的數據放到map2
        map2.putAll(map);
        //map2 = {鄧超=孫儷, 柳巖=baby, 汪峯=章子怡, 謝霆鋒=王菲, 黃曉明=baby}
        System.out.println("map2 = " + map2);

    }

    private static void method_1() {
        //使用子類創建對象
        //HashMap()構造一個具有默認初始容量 (16) 和默認加載因子 (0.75) 的空 HashMap。
        Map<String, String> map = new HashMap<>();//鍵和值的泛型類型可以不一致
        //添加數據
        //1)執行put添加數據的時候,如果新添加的鍵不存在,那麼此時直接添加,並返回null
        String s = map.put("黃曉明", "baby");
        System.out.println("s = " + s);//s = null
        System.out.println(map);//{黃曉明=baby}

        //對於鍵黃曉明已經存在了,此時put方法就是將新的值楊冪覆蓋之前舊的值baby 返回舊值baby給s1
        //2)執行put添加數據的時候,如果新添加的鍵存在,那麼新添加的value覆蓋之前舊的value,並返回舊的value
        String s1 = map.put("黃曉明", "楊冪");
        System.out.println("s1 = " + s1);//s1 = baby
        System.out.println(map);//{黃曉明=楊冪}
    }
}

小結:

 1.public V put(K key, V value)`:  把指定的鍵與指定的值添加到Map集合中。
        說明:
            1)執行put添加數據的時候,如果新添加的鍵不存在,那麼此時直接添加,並返回null
            2)執行put添加數據的時候,如果新添加的鍵存在,那麼新添加的value覆蓋之前舊的value,並返回舊的value
 2.public V remove(Object key)`: 把指定的鍵 所對應的鍵值對元素 在Map集合中刪除,返回被刪除元素的值。
 3.public V get(Object key)` 根據指定的鍵,在Map集合中獲取對應的值。
 4.public Set<K> keySet()`: 獲取Map集合中所有的鍵,存儲到Set集合中。
 5.public Set<Map.Entry<K,V>> entrySet()`: 獲取到Map集合中所有的鍵值對對象的集合(Set集合)。
            說明:該方法表示獲取Map集合中的所有的鍵值對,存放到單列集合Set中,鍵值對屬於Map.Entry<K,V>類型
 6.public boolean containKey(Object key)`:判斷該集合中是否有此鍵。 如果包含返回true,否則返回false
 7. int size() 返回此映射中的鍵-值映射關係數。 集合長度

5.Map的遍歷

1.使用keySet方法遍歷(瞭解)

  • 該方式需要使用的方法:
 public V get(Object key)` 根據指定的鍵,在Map集合中獲取對應的值。
 public Set<K> keySet()`: 獲取Map集合中所有的鍵,存儲到Set集合中。
  • 圖解
    在這裏插入圖片描述
  • 代碼實現
package com.itheima.sh.map_iterator_02;

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

/*
    使用keySet方法遍歷
 */
public class KeySetDemo01 {
    public static void main(String[] args) {
        //1.創建集合對象
        Map<String, String> map = new HashMap<>();
        //2.添加數據
        map.put("黃曉明", "baby");
        map.put("鄧超", "孫儷");
        map.put("汪峯", "章子怡");
        map.put("寶寶", "蓉蓉");
        //3.使用集合對象調用keySet方法獲取所有的鍵即老公
        Set<String> keys = map.keySet();
        //4.遍歷Set集合獲取每個鍵
        for(Iterator<String> it = keys.iterator();it.hasNext();){
            //獲取數據
            String key = it.next();
            //使用Map集合對象調用get方法根據key獲取value老婆
            String value = map.get(key);
            System.out.println(key+"--"+value);
        }
    }
}

小結:

1.上述使用keySet方式迭代了集合兩次。第一次是放到Iterator迭代器中,然後第二次是使用get方式。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kWZbdb4C-1592807422288)(/image-20200518111653376.png)]

2.使用entrySet方式遍歷Map集合(掌握)

  • 使用方法:

    • Map接口中的方法:

      public Set<Map.Entry<K,V>> entrySet()`: 獲取到Map集合中所有的鍵值對對象的集合(Set集合)。
                  說明:該方法表示獲取Map集合中的所有的鍵值對,存放到單列集合Set中,鍵值對屬於Map.Entry<K,V>
      
    • 使用Map.Entry接口中的方法:

      K getKey() 返回與此項對應的鍵。
      V getValue()  返回與此項對應的值。 
      
  • 圖解

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bPIMRpdC-1592807422289)(/image-20200518112903000.png)]

  • 代碼演示

    package com.itheima.sh.map_iterator_02;
    
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    /*
        使用entrySet方法遍歷
     */
    public class EntrySetDemo02 {
        public static void main(String[] args) {
            //1.創建集合對象
            Map<String, String> map = new HashMap<>();
            //2.添加數據
            map.put("黃曉明", "baby");
            map.put("鄧超", "孫儷");
            map.put("汪峯", "章子怡");
            map.put("寶寶", "蓉蓉");
            //3.獲取鍵值對整體對象放到Set集合中
            Set<Map.Entry<String, String>> entries = map.entrySet();
            //4.遍歷單列集合Set取出每個鍵值對對象即結婚證
            for(Iterator<Map.Entry<String, String>> it = entries.iterator();it.hasNext();){
                //5.取出鍵值對整體
                Map.Entry<String, String> entry = it.next();
                //6.使用entry對象調用方法獲取鍵和值
                String key = entry.getKey();
                String value = entry.getValue();
                //7.輸出
                System.out.println(key+"---"+value);
            }
        }
    }
    
    

    小結:

    1.以後都使用這種,因爲效率高,只迭代一次

    2.獲取鍵值對整體屬於Map.Entry類型,然後使用Map.Entry中的方法分別獲取出key和value:

    K getKey() 返回與此項對應的鍵。
    V getValue()  返回與此項對應的值。 
    

6.Map常用子類

1.HashMap類(必須掌握)

1.HashMap類底層是一個哈希表數據結構,控制鍵

2.要求HashMap鍵位置的對象所屬類必須重寫hashCode和equals方法

3.HashMap集合是jdk1.2開始有的:

1)線程不安全
2) 效率高
3)鍵和值可以是null
4) 存取無序

代碼演示:

package com.itheima.sh.hashmap_03;

import java.util.HashMap;

/*
    注意:底層哈希表控制鍵的,要求鍵位置的對象所屬類必須重寫hashCode和equals方法
 */
public class HashMapDemo01 {
    public static void main(String[] args) {
        //1.創建集合對象HashMap() 構造一個具有默認初始容量 (16) 和默認加載因子 (0.75) 的空 HashMap。
        HashMap<Student, String> hm = new HashMap<Student, String>();
        //2.向集合添加數據
        hm.put(new Student("張三", 18), "上海");
        hm.put(new Student("李四", 20), "北京");
        hm.put(new Student("王五", 19), null);
        hm.put(null, null);
        hm.put(null, null);
        hm.put(null, null);
        hm.put(null, null);
        hm.put(null, null);
        hm.put(null, null);
        //修改作用
        hm.put(new Student("張三", 18), "黑龍江");
        //hm = {Student{name='王五', age=19}=null, null=null, Student{name='張三', age=18}=黑龍江, Student{name='李四', age=20}=北京}

        System.out.println("hm = " + hm);
    }
}

小結:

1.HashMap屬於jdk1.2之後纔有的,替換了Hashtable,提高效率

2.底層哈希表數據結構控制鍵,所以要求鍵位置的對象所屬類必須重寫hashCode和equals方法

3.HashMap集合的鍵和值都可以是null,但是鍵位置只能是一個null

2.Hashtable類(瞭解)

1.數據jdk1.0就有的

2.安全的,但是效率低

3.底層是哈希表數據結構,控制鍵

4.該集合的鍵和值不允許是null

5.從1.2開始後被HashMap取代了,效率更高

代碼演示:

package com.itheima.sh.hashtable_04;

import java.util.Hashtable;

/*
    Hashtable類(瞭解)

    1.數據jdk1.0就有的

    2.安全的,但是效率低

    3.底層是哈希表數據結構,控制鍵

    4.該集合的鍵和值不允許是null

    5.從1.2開始後被HashMap取代了,效率更高
 */
public class HashtableDemo01 {
    public static void main(String[] args) {
        //創建集合對象 Hashtable() 用默認的初始容量 (11) 和加載因子 (0.75) 構造一個新的空哈希表。
        Hashtable<String, Integer> ht = new Hashtable<>();
        //添加數據
        ht.put("劉德華", 50);
        ht.put("張學友", 55);
        ht.put("郭富城", 52);
        ht.put("黎明", 51);
        ht.put("劉德華", 48);
        //Exception in thread "main" java.lang.NullPointerException 報空指針異常
        /*
            Hashtable的鍵和值不能是null的原因:
                public synchronized V put(K key, V value) {
                // Make sure the value is not null
                    if (value == null) {
                        throw new NullPointerException();
                    }
                    key是null的話這裏相當於null.hashCode() 空指針了
                    int hash = key.hashCode();
              }
         */
        ht.put(null, 20);

        System.out.println("ht = " + ht);

    }
}

3.LinkedHashMap(瞭解)

package com.itheima.sh.linkedhashmap_05;

import java.util.LinkedHashMap;

/*
    LinkedHashMap
    1.底層有兩個數據結構:
        1)哈希表:存儲數據保證數據唯一
        2)雙鏈表:保證存取有序
 */
public class LinkedHashMapDemo01 {
    public static void main(String[] args) {
        //LinkedHashMap()構造一個帶默認初始容量 (16) 和加載因子 (0.75) 的空插入順序 LinkedHashMap 實例。
        LinkedHashMap<String, Integer> ht = new LinkedHashMap<>();
        ht.put("劉德華", 50);
        ht.put("張學友", 55);
        ht.put("郭富城", 52);
        ht.put("黎明", 51);
        ht.put("劉德華", 48);
        //ht = {劉德華=48, 張學友=55, 郭富城=52, 黎明=51}
        System.out.println("ht = " + ht);
    }
}

小結:

LinkedHashMap
1.底層有兩個數據結構:
1)哈希表:存儲數據保證數據唯一
2)雙鏈表:保證存取有序

4.TreeMap類(瞭解)

1.底層是紅黑樹數據結構,控制鍵,可以對鍵進行排序。具體如何排序看使用的構造方法:

1) TreeMap() 對鍵是大小升序,非自定義類(String Integer)按照大小升序排序
2TreeMap(Comparator<? super K> comparator) 根據鍵按照指定規則進行排序,
    	參數:comparator屬於自定義比較器接口Comparator類型,具體的排序規則由我們實現該接口的排序方法指定:
    int compare(T o1, T o2)  
    	o1 - o2 升序
    	o2 - o1 降序

代碼演示:

package com.itheima.sh.treemap_06;

import java.util.Comparator;
import java.util.TreeMap;

/*
    1) TreeMap() 對鍵是大小升序,非自定義類(String Integer)按照大小升序排序,不能是自定義類,否則就會報ClassCastException
    2)TreeMap(Comparator<? super K> comparator) 根據鍵按照指定規則進行排序,
    	參數:comparator屬於自定義比較器接口Comparator類型,具體的排序規則由我們實現該接口的排序方法指定:
    int compare(T o1, T o2)
    	o1 - o2 升序
    	o2 - o1 降序
 */
public class TreeMapDemo01 {
    public static void main(String[] args) {
        method_3();
    }
    //需求:按照年齡從小往大排
    private static void method_3() {
        //創建集合對象
        TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.age - o2.age;
            }
        });
        //添加數據
        tm.put(new Student("張三", 20), "上海");
        tm.put(new Student("李四", 17), "杭州");
        tm.put(new Student("王五", 19), "北京");
        tm.put(new Student("張三", 20), "上海");
        System.out.println(tm);

    }

    //1.需求:按照整數的從大到小排序
    /*
        2)TreeMap(Comparator<? super K> comparator) 根據鍵按照指定規則進行排序,
    	參數:comparator屬於自定義比較器接口Comparator類型,具體的排序規則由我們實現該接口的排序方法指定:
            int compare(T o1, T o2)
                o1 - o2 升序
                o2 - o1 降序
     */
    private static void method_2() {
        //1.創建集合對象
        TreeMap<Integer, String> tm = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        //添加數據
        tm.put(50, "劉德華");
        tm.put(56, "張學友");
        tm.put(48, "郭富城");
        tm.put(53, "黎明");
        //tm = {56=張學友, 53=黎明, 50=劉德華, 48=郭富城}
        System.out.println("tm = " + tm);

    }

    //1) TreeMap() 對鍵是大小升序,非自定義類(String Integer)按照大小升序排序
    private static void method_1() {
        //1.創建集合對象
        TreeMap<String, String> tm = new TreeMap<>();
        //2.添加數據
        tm.put("abcdef", "劉德華");
        tm.put("ADDF", "張學友");
        tm.put("abc", "郭富城");
        tm.put("zhag", "黎明");
        //輸出 tm = {ADDF=張學友, abc=郭富城, abcdef=劉德華, zhag=黎明}
        System.out.println("tm = " + tm);
    }
}

小結:

  1. TreeMap() 對鍵是大小升序,非自定義類(String Integer)按照大小升序排序,不能是自定義類,否則就會報ClassCastException
    2)TreeMap(Comparator<? super K> comparator) 根據鍵按照指定規則進行排序,
    參數:comparator屬於自定義比較器接口Comparator類型,具體的排序規則由我們實現該接口的排序方法指定:
    int compare(T o1, T o2)
    o1 - o2 升序
    o2 - o1 降序

7.Map集合練習(課下必須完成)

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

代碼演示:

package com.itheima.sh.map_test_07;

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

/*
    需求:計算一個字符串中每個字符出現次數。
    分析:
        "akajahKLAK19"

        字符          次數
        a              3
        k              1
        j              1
        h              1
        K              1
        ...................
        1.map集合沒有字符那麼直接將字符和次數1存儲到map集合
        2.如果map集合中有字符,則根據字符獲取次數然後加1,在存儲到map集合中 put(a,3)
   步驟:
   1.創建鍵盤錄入的對象
   2.獲取錄入的字符串
   3.創建Map集合對象,字符作爲key  次數作爲value
   4.遍歷錄入的字符串取出每個字符
   5.判斷Map集合的key位置是否包含該字符
        不包含:說明是第一次操作該字符,將字符和次數1存儲到集合中
        包含:說明不是第一次操作字符,將字符作爲key結合value get(key)方法 獲取次數,然後次數+1,最後將字符以及加1後的次數存儲到
        map中
   6.遍歷map集合輸出字符和次數
 */
public class Test01 {
    public static void main(String[] args) {
        //1.創建鍵盤錄入的對象
        Scanner sc = new Scanner(System.in);
        //2.獲取錄入的字符串
        System.out.println("請您輸入一個字符串:");
        String inputStr = sc.next();
        //3.創建Map集合對象,字符作爲key  次數作爲value
        HashMap<Character, Integer> map = new HashMap<>();
        //4.遍歷錄入的字符串取出每個字符 inputStr.length().fori
        for (int i = 0; i < inputStr.length(); i++) {//i表示索引
            //獲取字符
            char key = inputStr.charAt(i);
            // 5.判斷Map集合的key位置是否包含該字符
            if(map.containsKey(key)){
                //包含:說明不是第一次操作字符,將字符作爲key結合value get(key)方法
                // map中 獲取次數,然後次數+1,最後將字符以及加1後的次數存儲到
                //獲取次數即value
                Integer countValue = map.get(key);
                //然後次數+1
                countValue++;
                //最後將字符以及加1後的次數存儲到
                map.put(key, countValue);
            }else{
                // 不包含:說明是第一次操作該字符,將字符和次數1存儲到集合中
                map.put(key, 1);
            }
        }
        //6.遍歷map集合輸出字符和次數
        //獲取鍵值對對象
        Set<Map.Entry<Character, Integer>> entries = map.entrySet();
        //遍歷set集合
        for (Map.Entry<Character, Integer> entry : entries) { //entry表示鍵值對對象
            //獲取key
            Character key = entry.getKey();
            Integer value = entry.getValue();
            // \t 表示製表符 就是tab
            System.out.println("字符:\t"+key+"\t次數:\t"+value);
        }

    }
}

8.集合的嵌套(掌握)

集合首先只能存儲引用數據類型,而集合本身就是引用數據類型,所以集合裏面還可以繼續存儲集合。在java中各種集合可以各種嵌套。

1.List嵌套List

package com.itheima.sh.collection_map_contains_08;

import java.util.ArrayList;
import java.util.Collections;

/*
    需求:假如有兩個班的學生姓名,它們分別存儲在兩個集合中,最後存儲到一個集合中。

    舉例:
    淘寶上買手機:
        賣家 裝手機:先裝裏面的,最後裝外面的(從裏向外添加)
        買家拆手機: 先拆外面的,最後獲取到裏面的(從外往裏獲取)
    嵌套集合使用規律:
        添加數據:(從裏向外添加)
        獲取數據:(從外往裏獲取)
 */
public class ListDemo01 {
    public static void main(String[] args) {
        //創建一個班的集合
        ArrayList<String> list1 = new ArrayList<>();
        //添加數據
        Collections.addAll(list1, "張三", "柳巖");

        ArrayList<String> list2 = new ArrayList<>();
        //添加數據
//        Collections.addAll(list2, "李四", "楊冪");

        //創建集合存儲list1 list2
        //List套List
        ArrayList<ArrayList<String>> allList = new ArrayList<>();
        //將list1 list2存儲到allList中
        //添加數據:(從裏向外添加)
        Collections.addAll(allList, list1, list2);
        //遍歷  獲取數據:(從外往裏獲取)
        //先獲取最外面的集合:allList  在獲取裏面的集合 list1 list2
        //先獲取最外面的集合:allList
        for (ArrayList<String> outList : allList) {
            //取出每個集合中的數據 第一次outList表示list1  第二次outList表示list2
            for (String s : outList) {
                System.out.println(s);
            }

        }

    }
}

小結:

1.嵌套集合使用規律:
添加數據:(從裏向外添加)
獲取數據:(從外往裏獲取)

2.List嵌套Map

package com.itheima.sh.collection_map_contains_08;

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

/*
    List嵌套Map集合
    需求:有兩個班的學員,分別存儲在兩個Map中,然後將兩個班的map存儲到一個ArrayList中。
 */
public class ListMapDemo02 {
    public static void main(String[] args) {
        //1.創建Map集合對象
        HashMap<String, String> map1 = new HashMap<>();
        map1.put("hiema001", "柳巖");
        map1.put("hiema002", "楊冪");

        HashMap<String, String> map2 = new HashMap<>();
        map2.put("itcast001", "郭德綱");
        map2.put("itcast002", "岳雲鵬");

        //2.創建ArrayList集合對象
        ArrayList<HashMap<String, String>> list = new ArrayList<>();
        list.add(map1);
        list.add(map2);
        //3.遍歷集合  添加:從裏向外添加  獲取:從外向裏獲取
        //3.1遍歷list集合
        for (HashMap<String, String> m : list) {
            //3.2遍歷map集合
            //3.2.1 獲取鍵值對
            Set<Map.Entry<String, String>> entries = m.entrySet();
            //3.2.2 獲取每個鍵值對
            for (Map.Entry<String, String> entry : entries) {
                //3.2.3 獲取鍵和值
                String key = entry.getKey();
                String value = entry.getValue();
                //3.2.4 輸出
                System.out.println(key+"----"+value);
            }
        }
    }
}

小結: 添加:從裏向外添加 獲取:從外向裏獲取

3.Map嵌套Map

package com.itheima.sh.collection_map_contains_08;

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

/*
    Map集合嵌套Map
        需求: 有兩個班,班號分別爲:"黑馬188期"和"黑馬189期",兩個班學員的姓名分別存儲在兩個Map中
 */
public class MapMapDemo03 {
    public static void main(String[] args) {
        //1.創建Map集合對象保存學號和姓名
        HashMap<String, String> map1 = new HashMap<>();
        map1.put("hiema001", "柳巖");
        map1.put("hiema002", "楊冪");

        HashMap<String, String> map2 = new HashMap<>();
        map2.put("itcast001", "郭德綱");
        map2.put("itcast002", "岳雲鵬");

        //2.創建Map集合保存班級和學號 姓名
        HashMap<String, HashMap<String, String>> allMap = new HashMap<>();
        allMap.put("黑馬188期", map1);
        allMap.put("黑馬189期", map2);
        
        //3.遍歷map: 從外向裏獲取
        //3.1獲取最外面集合的鍵值對對象
        Set<Map.Entry<String, HashMap<String, String>>> outEntries = allMap.entrySet();
        //3.2取出最外面集合中的每個鍵值對
        for (Map.Entry<String, HashMap<String, String>> outEntry : outEntries) {
            //3.3遍歷outEntry表示的外面集合的key和value
            String outKey = outEntry.getKey();
            System.out.println("班級是:"+outKey);
            //outValue表示 map1 map2
            HashMap<String, String> outValue = outEntry.getValue();
            //3.4遍歷outValue表示的map集合
            Set<Map.Entry<String, String>> InEntries = outValue.entrySet();
            for (Map.Entry<String, String> inEntry : InEntries) {
                //獲取inEntry集合的key和value
                String key = inEntry.getKey();
                String value = inEntry.getValue();
                System.out.println(key+"---"+value);
            }
        }
    }
}

小結: 添加:從裏向外添加 獲取:從外向裏獲取

9.使用集合模擬鬥地主遊戲編寫(課下必須完成)

  • 圖解

在這裏插入圖片描述

  • 代碼實現

    package com.itheima.sh.playcard_09;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    
    /*
        鬥地主遊戲編寫:
        步驟:
        1.準備牌
        2.洗牌
        3.發牌
        4.看牌
         小☺
     */
    public class PlayCard {
        public static void main(String[] args) {
            //1.準備牌
            //1.1創建map集合保存序號和撲克牌
            HashMap<Integer, String> mapPoker = new HashMap<>();
            //1.2創建集合保存序號
            ArrayList<Integer> numbersList = new ArrayList<>();
            //1.3創建集合存儲花色
            ArrayList<String> colors = new ArrayList<>();
            Collections.addAll(colors, "♣", "♦", "♠", "♥");
            //1.4創建集合存儲撲克牌數字
            ArrayList<String> numbers = new ArrayList<>();
            Collections.addAll(numbers, "2", "A", "K", "Q", "J");
            for (int i = 10; i >= 3; i--) {
                numbers.add(i+"");
            }
            //定義變量作爲mapPoker序號
            int index = 0;
            //先向撲克牌中添加大小王
            mapPoker.put(index, "大☺");
            //每次序號+1
            index++;
            mapPoker.put(index, "小☺");
            //每次序號+1
            index++;
            //numbers = [2, A, K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3]
    //        System.out.println("numbers = " + numbers);
            //1.5將花色和撲克牌的數字進行組合  ♣2 ♦2 ♠2 ♥2  ♣A ♦A ♠A ♥A
            //數字作爲外層循環
            for (String thisNumber : numbers) {
                //顏色作爲內層循環
                for (String thisColor : colors) {
                    //拼接
                    String thisCard = thisColor + thisNumber;
                    //將撲克牌放到map集合中
                    mapPoker.put(index,thisCard);//♣2
                    //每次序號+1
                    index++;
                }
            }
    
    //        System.out.println(mapPoker);
            //1.6添加序號
            for (int i = 0; i <= 53; i++) {
                numbersList.add(i);
            }
    //        System.out.println(numbersList);
    
            // 2.洗牌 洗序號
            Collections.shuffle(numbersList);
            //3.發牌 發的是序號
            //3.1創建三個玩家集合
            ArrayList<Integer> fage = new ArrayList<>();
            ArrayList<Integer> suoge = new ArrayList<>();
            ArrayList<Integer> yanyan = new ArrayList<>();
            ArrayList<Integer> dipai = new ArrayList<>();
            //3.2遍歷序號集合numbersList取出每個序號
            for (int i = 0; i < numbersList.size(); i++) {//i表示索引
                //3.3取出每個序號
                Integer thisNumber = numbersList.get(i);// numbersList.get(i)表示根據索引i獲取numbersList中的序號
                /*
                    3.4 最後三張留作底牌 其餘的牌分別發給三個玩家
                 */
                //判斷是否是最後三張底牌
                if(i>=numbersList.size() - 3){//51 52 53
                    //說明是最後三張底牌 放到底牌集合中
                    dipai.add(thisNumber);
                }else{
                    //說明不是最後三張底牌
                    /*
                        3.5將其餘牌發給玩家
                        發哥 摸一張
                        鎖哥 摸第二張
                        巖巖 摸第三張
                     */
                    if(i % 3 == 0){
                        //發哥
                        fage.add(thisNumber);
                    }else if(i % 3 == 1){
                        //鎖哥
                        suoge.add(thisNumber);
                    }else if(i % 3 == 2){
                        //巖巖
                        yanyan.add(thisNumber);
                    }
                }
            }
            //4.對玩家以及底牌排序
            Collections.sort(fage);
            Collections.sort(suoge);
            Collections.sort(yanyan);
            Collections.sort(dipai);
            //5.看牌
            lookCard(mapPoker,fage,"發哥");
            lookCard(mapPoker,suoge,"鎖哥");
            lookCard(mapPoker,yanyan,"巖巖");
            lookCard(mapPoker,dipai,"底牌");
    
        }
        /*
            mapPoker:存放的序號和撲克牌
            0  大王
            1  小王
            list:存放的是玩家序號  10 20 25
            name:接收的名字
         */
        private static void lookCard(HashMap<Integer, String> mapPoker, ArrayList<Integer> list, String name) {
            //創建StirngBuilder對象
            StringBuilder sb = new StringBuilder(name).append(":");
            //遍歷list集合取出每個序號
            for (Integer key : list) {
                //根據key獲取value即撲克牌
                String value = mapPoker.get(key);
                //將value即撲克牌放到緩衝區中
                sb.append(value).append("\t");
            }
            System.out.println(sb);
        }
    }
    
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章