1. 程式人生 > >day18(Map集合&模擬鬥地主洗牌和發牌)

day18(Map集合&模擬鬥地主洗牌和發牌)

###18.01_集合框架(Map集合概述和特點)

* A:Map介面概述

* 檢視API可以知道:

* 將鍵對映到值的物件

* 一個對映不能包含重複的鍵

* 每個鍵最多隻能對映到一個值

* B:Map介面和Collection介面的不同

* Map是雙列的,Collection是單列的

* Map的鍵唯一,Collection的子體系Set是唯一的

* Map集合的資料結構值針對鍵有效,跟值無關;Collection集合的資料結構是針對元素有效

 

###18.02_集合框架(Map集合的功能概述)

* A:Map集合的功能概述

* a:新增功能

* V put(K key,V value):新增元素。

* 如果鍵是第一次儲存,就直接儲存元素,返回null

* 如果鍵不是第一次存在,就用值把以前的值替換掉,返回以前的值

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

    Integer i1 = map.put("張三", 23);

    Integer i2= map.put("李四", 24);

    Integer i3 = map.put("王五", 25);

    Integer i4 = map.put("趙六", 26);

    Integer i5 = map.put("張三", 26);//相同的鍵不儲存,值覆蓋,把被覆蓋的值返回

 

    System.out.println(map);//{趙六=26, 張三=26, 李四=24, 王五=25}

 

    System.out.println(i1);//null

    System.out.println(i2);//null

    System.out.println(i3);//null

    System.out.println(i4);//null

    System.out.println(i5);//23

* b:刪除功能

* void clear():移除所有的鍵值對元素

* V remove(Object key):根據鍵刪除鍵值對元素,並把值返回

* c:判斷功能

* boolean containsKey(Object key):判斷集合是否包含指定的鍵

* boolean containsValue(Object value):判斷集合是否包含指定的值

* boolean isEmpty():判斷集合是否為空

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

    map.put("張三", 23);

    map.put("李四", 24);

    map.put("王五", 25);

    map.put("趙六", 26);

 

    //Integer value = map.remove("張三");//根據鍵刪除元素,返回鍵對應的值

    //System.out.println(value);//23

    System.out.println(map.containsKey("張三"));//判斷是否包含傳入的鍵

    System.out.println(map.containsValue(100));//判斷是否包含傳入的值

    System.out.println(map);

* d:獲取功能

* Set<Map.Entry<K,V>> entrySet():

* V get(Object key):根據鍵獲取值

* Set<K> keySet():獲取集合中所有鍵的集合

* Collection<V> values():獲取集合中所有值的集合

* e:長度功能

* int size():返回集合中的鍵值對的個數

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

    map.put("張三", 23);

    map.put("李四", 24);

    map.put("王五", 25);

    map.put("趙六", 26);

 

    Collection<Integer> c = map.values();

    System.out.println(c);//[26, 23, 24, 25]

    System.out.println(map.size());//4

 

###18.03_集合框架(Map集合的遍歷之鍵找值)

* A:鍵找值思路:

* 獲取所有鍵的集合

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

* 根據鍵找值

* B:案例演示

* Map集合的遍歷之鍵找值

 

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

hm.put("張三", 23);

hm.put("李四", 24);

hm.put("王五", 25);

hm.put("趙六", 26);

 

/*Set<String> keySet = hm.keySet(); //獲取集合中所有的鍵

Iterator<String> it = keySet.iterator(); //獲取迭代器

while(it.hasNext()) { //判斷單列集合中是否有元素

String key = it.next(); //獲取集合中的每一個元素,其實就是雙列集合中的鍵

Integer value = hm.get(key); //根據鍵獲取值

System.out.println(key + "=" + value); //列印鍵值對

}*/

 

for(String key : hm.keySet()) { //增強for迴圈迭代雙列集合第一種方式

System.out.println(key + "=" + hm.get(key));

}

###18.04_集合框架(Map集合的遍歷之鍵值對物件找鍵和值)

* A:鍵值對物件找鍵和值思路:

* 獲取所有鍵值對物件的集合

* 遍歷鍵值對物件的集合,獲取到每一個鍵值對物件

* 根據鍵值對物件找鍵和值

* B:案例演示

* Map集合的遍歷之鍵值對物件找鍵和值

 

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

hm.put("張三", 23);

hm.put("李四", 24);

hm.put("王五", 25);

hm.put("趙六", 26);

/*Set<Map.Entry<String, Integer>> entrySet = hm.entrySet(); //獲取所有的鍵值物件的集合

Iterator<Entry<String, Integer>> it = entrySet.iterator();//獲取迭代器

while(it.hasNext()) {

Entry<String, Integer> en = it.next(); //獲取鍵值對物件

String key = en.getKey(); //根據鍵值對物件獲取鍵

Integer value = en.getValue(); //根據鍵值對物件獲取值

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

}*/

 

for(Entry<String,Integer> en : hm.entrySet()) {

System.out.println(en.getKey() + "=" + en.getValue());

}

C:原始碼分析

HashMap----Entry

###18.05_集合框架(HashMap集合鍵是Student值是String的案例)

* A:案例演示

* HashMap集合鍵是Student值是String的案例

* 鍵是學生物件,代表每一個學生

 * 值是字串物件,代表學生歸屬地

public static void main(String[] args) {

HashMap<Student, String> hm = new HashMap<>();

hm.put(new Student("張三", 23), "北京");

hm.put(new Student("張三", 23), "上海");

hm.put(new Student("李四", 24), "廣州");

hm.put(new Student("王五", 25), "深圳");

 

System.out.println(hm);

}

###18.06_集合框架(LinkedHashMap的概述和使用)

* A:案例演示

* LinkedHashMap的特點

* 底層是連結串列實現的可以保證怎麼存就怎麼取

public static void main(String[] args) {

LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>();

lhm.put("張三", 23);

lhm.put("李四", 24);

lhm.put("趙六", 26);

lhm.put("王五", 25);

 

System.out.println(lhm);

}

###18.07_集合框架(TreeMap集合鍵是Student值是String的案例)

* A:案例演示

* TreeMap集合鍵是Student值是String的案例

public static void main(String[] args) {

//demo1();

TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() {

 

@Override

public int compare(Student s1, Student s2) {

int num = s1.getName().compareTo(s2.getName()); //按照姓名比較

return num == 0 ? s1.getAge() - s2.getAge() : num;

}

});

tm.put(new Student("張三", 23), "北京");

tm.put(new Student("李四", 13), "上海");

tm.put(new Student("趙六", 43), "深圳");

tm.put(new Student("王五", 33), "廣州");

 

System.out.println(tm);

}

public static void demo1() {

TreeMap<Student, String> tm = new TreeMap<>();

tm.put(new Student("張三", 23), "北京");

tm.put(new Student("李四", 13), "上海");

tm.put(new Student("王五", 33), "廣州");

tm.put(new Student("趙六", 43), "深圳");

 

System.out.println(tm);

}

###18.08_集合框架(統計字串中每個字元出現的次數)

* A:案例演示

* 需求:統計字串中每個字元出現的次數

String str = "aaaabbbcccccccccc";

char[] arr = str.toCharArray(); //將字串轉換成字元陣列

HashMap<Character, Integer> hm = new HashMap<>(); //建立雙列集合儲存鍵和值

 

for(char c : arr) { //遍歷字元陣列

/*if(!hm.containsKey(c)) { //如果不包含這個鍵

hm.put(c, 1); //就將鍵和值為1新增

}else { //如果包含這個鍵

hm.put(c, hm.get(c) + 1); //就將鍵和值再加1新增進來

}

 

//hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1);

Integer i = !hm.containsKey(c) ? hm.put(c, 1) : hm.put(c, hm.get(c) + 1);

}

 

for (Character key : hm.keySet()) { //遍歷雙列集合

System.out.println(key + "=" + hm.get(key));

}

 

 

###18.09_集合框架(集合巢狀之HashMap巢狀HashMap)

* A:案例演示

* 集合巢狀之HashMap巢狀HashMap

需求:

 * 雙元課堂有很多基礎班

 * 第88期基礎班定義成一個雙列集合,鍵是學生物件,值是學生的歸屬地

 * 第99期基礎班定義成一個雙列集合,鍵是學生物件,值是學生的歸屬地

 * 無論88期還是99期都是班級物件,所以為了便於統一管理,把這些班級物件新增到雙元課堂集合中

public static void main(String[] args) {

//定義88期基礎班

HashMap<Student, String> hm88 = new HashMap<>();

hm88.put(new Student("張三", 23), "北京");

hm88.put(new Student("李四", 24), "北京");

hm88.put(new Student("王五", 25), "上海");

hm88.put(new Student("趙六", 26), "廣州");

 

//定義99期基礎班

HashMap<Student, String> hm99 = new HashMap<>();

hm99.put(new Student("唐僧", 1023), "北京");

hm99.put(new Student("孫悟空",1024), "北京");

hm99.put(new Student("豬八戒",1025), "上海");

hm99.put(new Student("沙和尚",1026), "廣州");

 

//定義雙元課堂

HashMap<HashMap<Student, String>, String> hm = new HashMap<>();

hm.put(hm88, "第88期基礎班");

hm.put(hm99, "第99期基礎班");

 

//遍歷雙列集合

for(HashMap<Student, String> h : hm.keySet()) { //hm.keySet()代表的是雙列集合中鍵的集合

String value = hm.get(h); //get(h)根據鍵物件獲取值物件

//遍歷鍵的雙列集合物件

for(Student key : h.keySet()) { //h.keySet()獲取集合總所有的學生鍵物件

String value2 = h.get(key);

 

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

}

}

}

###18.10_集合框架(HashMap和Hashtable的區別)

* A:面試題

* HashMap和Hashtable的區別

* Hashtable是JDK1.0版本出現的,是執行緒安全的,效率低,HashMap是JDK1.2版本出現的,是執行緒不安全的,效率高

* Hashtable不可以儲存null鍵和null值,HashMap可以儲存null鍵和null值

* B:案例演示

* HashMap和Hashtable的區別

public static void main(String[] args) {

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

hm.put(null, 23);

hm.put("李四", null);

System.out.println(hm);

 

/*Hashtable<String, Integer> ht = new Hashtable<>();

//ht.put(null, 23);

ht.put("張三", null);

System.out.println(ht);*/

 

System.out.println("1111111111111");

}

###18.11_集合框架(Collections工具類的概述和常見方法講解)

* A:Collections類概述

* 針對集合操作 的工具類

* B:Collections成員方法

*

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

public static <T> int binarySearch(List<?> list,T key)

public static <T> T max(Collection<?> coll)

public static void reverse(List<?> list)

public static void shuffle(List<?> list)

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

    list.add("c");

    list.add("a");

    list.add("a");

    list.add("b");

    list.add("d");

 

    System.out.println(list);//[c, a, a, b, d]

    Collections.sort(list);//將集合排序

    System.out.println(list);//[a, a, b, c, d]

 

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

    list.add("a");

    list.add("c");

    list.add("d");

    list.add("f");

    list.add("g");

    //如果搜尋鍵包含在列表中,則返回搜尋鍵的索引;否則返回 (-(插入點) - 1)。

    System.out.println(Collections.binarySearch(list,"c"));//1

    System.out.println(Collections.binarySearch(list,"b"));//-2

 

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

    list.add("a");

    list.add("c");

    list.add("d");

    list.add("g");

    list.add("f");

    //System.out.println(Collections.max(list));//g//根據預設排序結果獲取集合中的最大值

    //Collections.reverse(list);//反轉集合

    Collections.shuffle(list);//隨機置換,可以用來洗牌

    System.out.println(list);//[a, c, f, g, d]

###18.12_集合框架(模擬鬥地主洗牌和發牌)

* A:案例演示

* 模擬鬥地主洗牌和發牌,牌沒有排序

 

//買一副撲克

String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};

String[] color = {"方片","梅花","紅桃","黑桃"};

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

 

for(String s1 : color) {

for(String s2 : num) {

poker.add(s1.concat(s2));

}

}

 

poker.add("小王");

poker.add("大王");

//洗牌

Collections.shuffle(poker);

//發牌

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

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

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

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

 

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

if(i >= poker.size() - 3) {

dipai.add(poker.get(i));

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

gaojin.add(poker.get(i));

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

longwu.add(poker.get(i));

}else {

me.add(poker.get(i));

}

}

 

//看牌

 

System.out.println(gaojin);

System.out.println(longwu);

System.out.println(me);

System.out.println(dipai);

 

###18.13_集合框架(模擬鬥地主洗牌和發牌並對牌進行排序的原理圖解)

* A:畫圖演示

* 畫圖說明排序原理

 

###18.14_集合框架(模擬鬥地主洗牌和發牌並對牌進行排序的程式碼實現)

* A:案例演示

* 模擬鬥地主洗牌和發牌並對牌進行排序的程式碼實現

*

//買一副牌

String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};

String[] color = {"方片","梅花","紅桃","黑桃"};

HashMap<Integer, String> hm = new HashMap<>(); //儲存索引和撲克牌

ArrayList<Integer> list = new ArrayList<>(); //儲存索引

int index = 0; //索引的開始值

for(String s1 : num) {

for(String s2 : color) {

hm.put(index, s2.concat(s1)); //將索引和撲克牌新增到HashMap中

list.add(index); //將索引新增到ArrayList集合中

index++;

}

}

hm.put(index, "小王");

list.add(index);

index++;

hm.put(index, "大王");

list.add(index);

//洗牌

Collections.shuffle(list);

//發牌

TreeSet<Integer> gaojin = new TreeSet<>();

TreeSet<Integer> longwu = new TreeSet<>();

TreeSet<Integer> me = new TreeSet<>();

TreeSet<Integer> dipai = new TreeSet<>();

 

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

if(i >= list.size() - 3) {

dipai.add(list.get(i)); //將list集合中的索引新增到TreeSet集合中會自動排序

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

gaojin.add(list.get(i));

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

longwu.add(list.get(i));

}else {

me.add(list.get(i));

}

}

 

//看牌

lookPoker("高進", gaojin, hm);

lookPoker("龍五", longwu, hm);

lookPoker("馮佳", me, hm);

lookPoker("底牌", dipai, hm);

 

}

 

public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer, String> hm) {

System.out.print(name + "的牌是:");

for (Integer index : ts) { //i代表雙列集合中的每一個鍵

System.out.print(hm.get(index) + " ");

}

 

System.out.println();

}

###18.15_集合框架(泛型固定下邊界)

* ? super E

public class BaseStudentextends Student {

    public BaseStudent() {

    }

    public BaseStudent(String name,int age) {

super(name, age);

    }

}

 

    //泛型固定上邊界 ? extends E

    ArrayList<Student> list1 = new ArrayList<Student>();

    list1.add(new Student("張三", 23));

    list1.add(new Student("李四", 24));

 

    ArrayList<BaseStudent> list2 =new ArrayList<BaseStudent>();

    list2.add(new BaseStudent("王五", 25));

    list2.add(new BaseStudent("趙六", 26));

 

    list1.addAll(list2);

 

    //泛型固定下邊界 ? super E

    public class Demo2_Genric {

    public static void main(String[] args) {

        TreeSet<Student> ts1 =new TreeSet<Student>(new CompareByAge());

        ts1.add(new Student("張三", 33));

        ts1.add(new Student("李四", 13));

        ts1.add(new Student("王五", 23));

        ts1.add(new Student("趙六", 43));

 

        TreeSet<BaseStudent> ts2 = new TreeSet<BaseStudent>(new CompareByAge());

        ts2.add(new BaseStudent("張三", 33));

        ts2.add(new BaseStudent("李四", 13));

        ts2.add(new BaseStudent("王五", 23));

        ts2.add(new BaseStudent("趙六", 43));

 

        System.out.println(ts2);

    }

}

class CompareByAgeimplements Comparator<Student> {

    @Override

    public int compare(Student s1, Student s2) {

int num = s1.getAge() - s2.getAge();//比較年齡

return num == 0 ? s1.getName().compareTo(s2.getName()) :  num;

    }

}

###18.16_day18總結:

Collection

 *List(存取有序,有索引,可以重複)

 *ArrayList

  底層是陣列實現的,執行緒不安全,查詢和修改快,增和刪比較慢

 *LinkedList

  底層是連結串列實現的,執行緒不安全,增和刪比較快,查詢和修改比較慢

 *Vector

  底層是陣列實現的,執行緒安全的,無論增刪改查都慢

  如果查詢和修改多,用ArrayList

  如果增和刪多,用LinkedList

  如果都多,用ArrayList

 *Set(存取無序,無索引,不可以重複)

 *HashSet

  底層是雜湊演算法實現

 *LinkedHashSet

  底層是連結串列實現,但是也是可以保證元素唯一,和HashSet原理一樣

 *TreeSet

  底層是二叉樹演算法實現

  一般在開發的時候不需要對儲存的元素排序,所以在開發的時候大多用HashSet,HashSet的效率比較高

  TreeSet在面試的時候比較多,問你有幾種排序方式,和幾種排序方式的區別

 * Map

 *HashMap

  底層是雜湊演算法,針對鍵

 *LinkedHashMap

  底層是連結串列,針對鍵

 *TreeMap

  底層是二叉樹演算法,針對鍵

  開發中用HashMap比較多