day09【Map、鬥地主排序、冒泡排序】HashMap、LinkedHashMap、TreeMap、集合嵌套、鬥地主案例、冒泡排序

day09【Map、鬥地主排序、冒泡排序】

反饋和複習
a.比較器口訣: 升序 前-(源碼)
b.爲什麼保證元素的唯一性.重寫hashCode和equals
    因爲Hash表結構,底層就是根據hashCode和equals來判斷兩個元素是否重複
1.Collection: 7+1
2.List: 7+1+4
    ArrayList: 7+1+4
    LinkedList: 7+1+4+8
3.Set:7+1
    HashSet:7+1   無序
    LinkedHashSet:7+1 有序
    TreeSet:7+1 無序(有自然順序的)
4.Collections    
     shuffle(List list); 打亂集合順序
     sort(List list); 對集合元素進行排序(默認升序)
     sort(List list,Comparator 比較器); 自定義排序規則(升序 前-)   
今日內容
1.Map集合(和Collection沒有直接的聯繫)
2.集合的嵌套(集合的元素還是集合) 
3.鬥地主發牌案例(必須3遍以上) 
4.冒泡排序算法(a.算法過程 b.算法的代碼實現)    

第一章 Map集合【重點】

1.1 Map的概述以及其特點
什麼是Map集合:
	Collection集合稱爲單列集合,Map集合稱爲雙列集合
Map集合的特點:
	a.Collection每個元素單獨存在(單列),Map每個元素成對存在(雙列)
    b.Map集合鍵必須是唯一的,值是可以重複的 
    c.Collection<E>中泛型只有一個,Map<K,V>中泛型有兩個(其中K代表鍵的類型,V代表值的類)    

在這裏插入圖片描述

1.2 Map的3個常用實現類以及其特點
Map接口有三個常見的實現類:
	HashMap: 底層採用哈希表結構, 無序
    LinkedHashMap:底層採用鏈表+哈希表結構,有序
    TreeMap: 底層採用紅黑樹結構,無序(但是鍵有自然順序) 
    重點: Map中爲了保證鍵的唯一性,如果鍵是自定義類型,必須重寫鍵的hashCode和equals方法    
1.3 Map接口定義的通用方法【重點】
: V put(K 鍵,V 值); 添加一個鍵值對,返回null
刪: V remove(K 鍵);根據鍵去刪除鍵值對,返回被刪除的鍵值對的值
改: V put(K 鍵,V 值); 添加一個重複的鍵時,該方法變成修改,返回修改前的值
查: V get(K 鍵); 根據鍵獲取對應的值
其他:
	public boolean containsKey(Object 鍵); 判斷Map中是否包含該鍵
    public boolean containsValue(Object 值); 判斷Map中是否包含該值   
        
使用Map中通用方法:
public class TestMap {
    public static void main(String[] args) {
        //1.創建一個Map的實現類對象
        HashMap<String,Integer> map = new HashMap<String, Integer>();
        //2.添加幾個
        map.put("張三",18);
        map.put("李四",28);
        map.put("王五",38);
        map.put("趙六",48);
        map.put("前妻",8);
        map.put("王八",88);
        //3.打印
        //{李四=28, 張三=18, 前妻=8, 王五=38, 趙六=48, 王八=88}
        System.out.println(map);
        //4.刪除
        Integer v1 = map.remove("王五");
        System.out.println(v1);
        System.out.println(map);
        //5.獲取
        Integer v2 = map.get("張三");
        System.out.println(v2);
        System.out.println(map);
        //6.修改,也是調用put
        Integer v3 = map.put("前妻", 9);
        System.out.println(v3);
        System.out.println(map);
        //7.判斷
        boolean b1 = map.containsKey("趙七");
        System.out.println(b1);

        boolean b2 = map.containsValue(18);
        System.out.println(b2);
    }
}	
1.4 Map的遍歷【非常重點】
  • 遍歷方式一
    第一種方式稱爲:以鍵找值
    public class TestMap01 {
        public static void main(String[] args) {
            //第一種遍歷方式:以鍵找值
            //1.創建一個Map的實現類對象
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            //2.添加幾個
            map.put("張三", 18);
            map.put("李四", 28);
            map.put("王五", 38);
            map.put("趙六", 48);
            map.put("前妻", 8);
            map.put("王八", 88);
            //3.獲取所有的鍵
            Set<String> keys = map.keySet();
            //4.遍歷這個keys集合
            for (String key : keys) {
                //5.以鍵找值
                Integer value = map.get(key);
                System.out.println(key + "..." + value);
            }
        }
    }    
    

在這裏插入圖片描述

  • 遍歷方式二
    第二種方式稱爲:鍵值對方式
    public class TestMap02 {
        public static void main(String[] args) {
            //第一種遍歷方式:以鍵找值
            //1.創建一個Map的實現類對象
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            //2.添加幾個
            map.put("張三", 18);
            map.put("李四", 28);
            map.put("王五", 38);
            map.put("趙六", 48);
            //Map集合遍歷的第二種方式:鍵值對方式
            //3.獲取Map中所有的鍵值對
            Set<Map.Entry<String, Integer>> entries = map.entrySet();
            //4.遍歷這個entries集合
            for (Map.Entry<String, Integer> entry : entries) {
                //5.從entry中取出鍵和值
                String key = entry.getKey();
                Integer value = entry.getValue();
                //6.打印
                System.out.println(key+"..."+value);
            }
        }
    }
        
    

    在這裏插入圖片描述

1.5 HashMap存儲自定義類型的鍵
需求:
	創建一個Map,學生作爲鍵, 家庭住址作爲值。
    HashMap<Student,String>
public class TestDemo {
    public static void main(String[] args) {
        //創建一個Map,學生作爲鍵, 家庭住址作爲值。
        //1.創建集合
        HashMap<Student,String> map = new HashMap<Student, String>();
        //2.添加數據
        map.put(new Student("jack",12),"北京中關村");
        map.put(new Student("rose",16),"南京中關村");
        map.put(new Student("marry",20),"天津中關村");
        map.put(new Student("tom",12),"東京中關村");
        //3.打印
        //{Student{name=jack,age=12}="北京中關村",鍵=值,鍵=值,鍵=值}
        System.out.println(map);
        //4.我要修改rose的地址
        map.put(new Student("rose",16),"廣東東莞");
        System.out.println(map);
    }
}
結論:
	如果鍵是自定義類型,爲了保證鍵的唯一性,必須重寫hashCode和equals方法       
1.6 LinkedHashMap介紹
HashMap底層採用哈希表結構,是無序的
LinkedHashMap底層採用鏈表+哈希表結構,是有序的

public class TestLinkedHashMap {
    public static void main(String[] args) {
        //1.創建一個LinkedHashMap
        LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
        //2.添加幾個
        map.put("rose",20);
        map.put("jack",10);
        map.put("marry",40);
        map.put("tom",30);
        //3.打印
        System.out.println(map);
    }
}    
1.7 TreeMap集合
a.TreeMap底層採用紅黑樹結構
TreeMap也是無序的,會按照鍵的自然順序默認升序
    
public class TestTreeMap {
    public static void main(String[] args) {
        //1.創建一個TreeMap集合
        TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
        //2.添加
        treeMap.put(20,"李四");
        treeMap.put(30,"王五");
        treeMap.put(40,"趙六");
        treeMap.put(10,"張三");
        //3.打印
        System.out.println(treeMap);
    }
}

擴展:
	如果鍵是數值類型,那麼按照鍵值的大小升序
    如果鍵是字符類型,那麼按照鍵的碼值的大小升序 
    如果鍵是字符串類型,那麼按照鍵的首字母大小升序,如果首字母相同按照次字母,依次類推...
    這四種的結論是一樣: Arrays.sort Collections.sort TreeSet  TreeMap  
        
b.我們也可以使用比較器排序
    使用TreeMap的另外一個構造即可
        public TreeMap(Comparator 比較器);

    public class TestTreeMap {
        public static void main(String[] args) {
            //1.創建一個TreeMap集合
    //        TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
            TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    //口訣: 升序 前-後
                    return o2-o1;
                }
            });
            //2.添加
            treeMap.put(20,"李四");
            treeMap.put(30,"王五");
            treeMap.put(40,"趙六");
            treeMap.put(10,"張三");
            //3.打印
            System.out.println(treeMap);


            //4.創建TreeMap集合,鍵是自定義類型
            TreeMap<Student, String> map = new TreeMap<Student,String>(new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    //按照年齡降序
    //                return o2.age-o1.age;
                    //按照姓名的長度升序
                    return o1.name.length()-o2.name.length();
                }
            });
            //5.添加數據
            map.put(new Student("jack",20),"北京");
            map.put(new Student("ady",10),"南京");
            map.put(new Student("marry",8),"東京");
            map.put(new Student("hanmeimei",15),"西京");

            //6.打印
            System.out.println(map);
        }
    }
1.8 Map集合練習【重點】
面試題:
	輸入一個字符串中每個字符出現次數。
        
public class TestDemo {
    public static void main(String[] args) {
        //輸入一個字符串中每個字符出現次數。
        //分析:
        //最後的結果是什麼樣?? a=3 b=2 c=10 d=5
        //1.定義一個map
        LinkedHashMap<Character,Integer> map = new LinkedHashMap<Character, Integer>();
        //2.輸入一個字符串
        System.out.println("請輸入一個字符串:");
        String str = new Scanner(System.in).nextLine();
        //abcdabcdac
        //3.遍歷字符串
        for (int i = 0; i < str.length(); i++) {
            //4.取出字符串中的某個字符
            char ch = str.charAt(i);
            //5.這個字符ch以前出現過
            if (map.containsKey(ch)){
                Integer oldCount = map.get(ch);
                map.put(ch,oldCount+1);
            }else{
                //5.這個字符ch以前沒出現過
                map.put(ch,1);
            }
        }
        //4.打印結果 map
        System.out.println(map);
    }
}        

第二章 集合的嵌套【難點&重點】

什麼是集合的嵌套
集合中的元素還是一個集合
2.1 List嵌套List
a.使用List集合保證兩個班的學生名字
    
public class TestListList {
    public static void main(String[] args) {
        //a.使用List集合保證兩個班的學生名字
        //1.創建集合保存一個班級學生
        ArrayList<String> ban1 = new ArrayList<String>();
        ban1.add("jack");
        ban1.add("rose");
        ban1.add("tom");

        //2.創建集合保存一個班級學生
        ArrayList<String> ban2 = new ArrayList<String>();
        ban2.add("小花");
        ban2.add("小草");
        ban2.add("小狗");

        //3.將ban1和ban2兩個集合,保存到一個大集合中
        ArrayList<ArrayList<String>> bans = new ArrayList<>();
        bans.add(ban1);
        bans.add(ban2);

        //4.自己遍歷
        for (ArrayList<String> ban : bans) {
            for (String name : ban) {
                System.out.println(name);
            }
        }
        //5.直接打印
//        System.out.println(bans);//[[],[]]
    }
}    
2.2 List嵌套Map
a.保存兩個班學生的名字以及對應的年齡
public class TestListMap {
    public static void main(String[] args) {
        //a.保存兩個班學生的名字以及對應的年齡
        //1.保存第一個班級學生的姓名和年齡
        HashMap<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("jack",12);
        map1.put("rose",11);
        map1.put("tom",10);

        //2.保存第二個班級學生的姓名和年齡
        HashMap<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("張鵬",18);
        map2.put("徐睿",19);
        map2.put("張亭",17);

        //3.創建一個大集合 保存兩個map
        ArrayList<HashMap<String, Integer>> maps = new ArrayList<HashMap<String, Integer>>();
        maps.add(map1);
        maps.add(map2);

        //4.直接打印
        System.out.println(maps); //[{},{}]

        //5.自己遍歷
        for (HashMap<String, Integer> map : maps) {
            Set<String> keys = map.keySet();
            for (String key : keys) {
                Integer value = map.get(key);
                System.out.println(key+".."+value);
            }
        }
    }
}    
2.3 Map嵌套Map
a.保證兩個班的名字和班裏同學的姓名以及對應的年齡
public class TestMapMap {
    public static void main(String[] args) {
        //a.保證兩個班的名字和班裏同學的姓名以及對應的年齡
        //1.保存第一個班級同學的姓名和年齡
        HashMap<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("jack",12);
        map1.put("rose",11);
        map1.put("tom",10);

        //2.保存第二個班級同學的姓名和年齡
        HashMap<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("張鵬",18);
        map2.put("徐睿",19);
        map2.put("張亭",17);

        //3.將兩個班級的map集合,保存到另外一個集合中,要求有該班級的名字
        HashMap<String,HashMap<String, Integer>> all = new HashMap<String, HashMap<String, Integer>>();
        all.put("一班",map1);
        all.put("二班",map2);

        //4.直接打印
        System.out.println(all);// {"一班"={jack=12,rose=11,tom=10},鍵=值}

        //5.手動遍歷
        //1.獲取所有的鍵
        Set<String> names = all.keySet();
        //2.遍歷所有的鍵
        for (String name : names) {
            //3.以鍵找值
            HashMap<String, Integer> map = all.get(name);
            //4.獲取該map所有的鍵
            Set<String> ns = map.keySet();
            //5.遍歷ns
            for (String n : ns) {
                //6.以鍵找值
                Integer value = map.get(n);
                System.out.println(n+"..."+value);
            }
        }
    }
}    

第三章 模擬鬥地主洗牌發牌【重點,至少3遍】

3.1 案例介紹

需求: 模擬鬥地主發牌,看牌(但是不打牌)   

在這裏插入圖片描述

3.2 案例分析

步驟分析:
1.準備 編號和牌 組成的Map集合
2.準備一副牌(54個編號)
3.洗牌(打亂集合)
4.發牌(遍歷集合)
5.排序(sort方法)
6.轉牌(以鍵找值)
7.打印給用戶看

3.3 代碼實現

public class TestDouDiZhu {
    public static void main(String[] args) {
        //1.準備 編號和牌 組成的Map集合
        LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
        //a.花色 4種
        String[] colors = {"♠", "♥", "♣", "♦"};
        //b.數值 13種
        String[] nums = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
        //c.編號變量
        int id = 1;
        //d.組合牌
        for (String num : nums) {
            for (String color : colors) {
                String card = color + num;
                //保存到map集合中
                map.put(id, card);
                id++;
            }
        }
        //e.單獨添加大小王
        map.put(53, "小S");
        map.put(54, "大S");

        //2.準備一副牌(54個編號)
        ArrayList<Integer> cards = new ArrayList<Integer>();
        for (int i = 1; i < 55; i++) {
            cards.add(i);
        }
        //3.洗牌(打亂集合)
        Collections.shuffle(cards);
        //4.發牌(遍歷集合)
        ArrayList<Integer> player1 = new ArrayList<Integer>();
        ArrayList<Integer> player2 = new ArrayList<Integer>();
        ArrayList<Integer> player3 = new ArrayList<Integer>();
        ArrayList<Integer> diPai = new ArrayList<Integer>();
        //遍歷集合
        //此處不能使用增強for
        for (int i = 0; i < cards.size() - 3; i++) {
            //取出每一張牌
            Integer card = cards.get(i);
            //給誰呢?????????????????????????????????
            //i = 0 3 6 p1
            //i = 1 4 7 p2
            //i = 2 5 8 p3
            if (i % 3 == 0) {
                player1.add(card);
            } else if (i % 3 == 1) {
                player2.add(card);
            }else{
                player3.add(card);
            }
        }

        //最後張三留給底牌
        diPai.add(cards.get(53));
        diPai.add(cards.get(52));
        diPai.add(cards.get(51));
        //5.排序(sort方法)
        Collections.sort(player1);
        Collections.sort(player2);
        Collections.sort(player3);
        Collections.sort(diPai);

        //6.看牌
        lookCards(player1,map);
        lookCards(player2,map);
        lookCards(player3,map);
        lookCards(diPai,map);

    }
    //看牌方法
    public static void lookCards(ArrayList<Integer> idCards, LinkedHashMap<Integer, String> map) {
        //遍歷
        for (Integer idCard : idCards) {
            String card = map.get(idCard);
            System.out.print(card+" ");
        }
        System.out.println();
    }
}

第四章 冒泡排序算法【理解】

4.1 冒泡排序的介紹
所有冒泡排序的思想是這樣的:
	依次比較數組中相連的兩元素,然後將較大元素放在後面,最後按照從小到大順序排列出來
        
規律:
	n個數比較,一共需要比較n-1輪
    第1,需要比較n-1,以後每輪比較的次數會遞減    
4.2 過程圖解(見圖解)

在這裏插入圖片描述

4.3 代碼實現
冒泡排序算法:
public class TestBubbleSort {
    public static void main(String[] args) {
        //準備一個數組
        int[] arr = {4, 6, 1, 3, 8, 2, 9, 7, 5};
        //排序
        //一共需要幾輪??? arr.length - 1輪
        //外層循環,控制輪數
        for(int i = 0;i < arr.length - 1;i++) {
            // i = 0 1 2
            //內存循環,控制比較的次數
            for(int j = 0;j < arr.length - 1 - i;j++){
                //比較的兩個元素:
                if (arr[j] > arr[j+1]){ //前100 > 後10
                    int temp =  arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        //測試一下
        System.out.println(Arrays.toString(arr));
    }
}	
總結
1.Map接口定義的共性方法【必須掌握】
    	put(,);
		remove();
		put(重複的鍵,);
		get()
            
        containsKey();
		containsValue();
2.Map各種實現類的遍歷方式(a.以鍵找值 b.鍵值對方式)【必須掌握】
    	a.以鍵找值
    		Set<K> keys = map.keySet(); //獲取所有鍵的集合
			for(K key : keys){ //遍歷所有的鍵
                V value = map.get(key)//以鍵找值
                //打印
                sout(key,value);    
            }
		b.鍵值對方式
            Set<Map.Entry<K,V>> entrys = map.entrySet();//獲取所有的鍵值對的集合
			for(Map.Entry<K,V> entry : entrys){//遍歷這個鍵值對集合
             	K key = entry.getKey();//獲取鍵值對中的鍵和值  
                V value = entry.getValue();//獲取鍵值對中的鍵和值  
                //打印
                sout(key,value);   
            }
    
3.集合嵌套【難點,開發中見的不多】
    a。List套List:
    	ArrayList<ArrayList<String>> arr;
    b。List套Map
        ArrayList<HashMap<String,Integer>> map
    c。Map套Map
    	HashMap<String,HashMap<String,Integer>> map
4.鬥地主牌【必須掌握】
    至少3!!!    
    
5.冒泡排序【理解】
      a。理解冒泡過程
      b。算法背下來
        	for(int i = 0;i<arr.length-1;i++){
                for(int j = 0;j<arr.length-1-i;j++){
                	if(arr[j]>arr[j+1]){
                        int temp = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = temp;
                    }
                }  
            }
        
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章