1. Map集合概述和特点

  • Map接口概述

    • 查看API可以知道:

      • 将键映射到值的对象

      • 一个映射不能包含重复的键

      • 每个键最多只能映射到一个值

    • 接口 Map<K,V>

      • 类型参数:

        • K - 此映射所维护的键的类型

        • V - 映射值的类型

    • 此接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个接口。
  • Map接口和Collection接口的不同

    • Map是双列的,Collection是单列的

    • Map的键唯一,Collection的子体系Set是唯一的

    • Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效

 

2. Map集合的功能概述

  • Map集合的功能概述

    • 添加功能

      • V put(K key,V value):添加元素。

        • 如果键是第一次存储,就直接存储元素,返回null

        • 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

    • 删除功能

      • void clear():移除所有的键值对元素

      • V remove(Object key):根据键删除键值对元素,并把值返回

    • 判断功能

      • boolean containsKey(Object key):判断集合是否包含指定的键

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

      • boolean isEmpty():判断集合是否为空

    • 获取功能

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

      • V get(Object key):根据键获取值

      • Set<K> keySet():获取集合中所有键的集合

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

    • 长度功能

      • int size():返回集合中的键值对的个数

    • package com.heima.map;
      
      import java.util.Collection;
      import java.util.HashMap;
      import java.util.Map;
      import java.util.Set;
      
      public class Demo1_Map {
      
          /**
           Map集合的功能概述
      
              1. 添加功能
                  V put(K key,V value):添加元素。
                      如果键是第一次存储,就直接存储元素,返回null
                      如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
      
              2. 删除功能
                  void clear():移除所有的键值对元素
                  V remove(Object key):根据键删除键值对元素,并把值返回
      
              3. 判断功能
                  boolean containsKey(Object key):判断集合是否包含指定的键
                  boolean containsValue(Object value):判断集合是否包含指定的值
                  boolean isEmpty():判断集合是否为空
      
              4. 获取功能
                  Set<Map.Entry<K,V>> entrySet():
                      V get(Object key):根据键获取值
                      Set<K> keySet():获取集合中所有键的集合
                      Collection<V> values():获取集合中所有值的集合
      
              5. 长度功能
                  int size():返回集合中的键值对的个数
           */
          public static void main(String[] args) {
      //        demo1();
      //        demo2();
      //        demo3();
              demo4();
              
          }
      
          public static void demo4() {
              Map<String, Integer> map = new HashMap<>();
              map.put("Ann",23);
              map.put("Bill",24);
              map.put("Carolle",25);
              map.put("Dell",21);
              
              Collection<Integer> v_set = map.values();  // 获取集合中所有值的集合
              System.out.println(v_set);
              
              Set<String> k_set = map.keySet();  // 获取集合中所有键的集合
              System.out.println(k_set);
              
              System.out.println(map.size());   // 返回集合中的键值对的个数
          }
      
          public static void demo3() {
              Map<String, Integer> map = new HashMap<>();
              map.put("Ann",23);
              map.put("Bill",23);
              map.put("Carolle",23);
              map.put("Dell",23);
              
              boolean b1 = map.containsKey("Dell");  // 判断集合是否包含指定的键
              boolean b2 = map.containsValue(23);  // 判断集合是否包含指定的值
              System.out.println(b1);
              System.out.println(b2);
          }
      
          public static void demo2() {
              Map<String, Integer> map = new HashMap<>();
              map.put("Ann",23);
              map.put("Bill",23);
              map.put("Carolle",23);
              map.put("Dell",23);
              
              Integer v1 = map.remove("Dell");
              System.out.println(v1);  // 返回删除键对应的值
              System.out.println(map);
              
              map.clear(); // 清空键值对
              System.out.println(map);
          }
      
          public static void demo1() {
              Map<String, Integer> map = new HashMap<>();
              Integer v1 = map.put("Ann", 23);  // 若key不存在,则返回null
              Integer v2 = map.put("Bill", 13);
              Integer v3 = map.put("Carolle", 33);
              Integer v4 = map.put("Dell", 43);
              Integer v5 = map.put("Mary", 25);
              Integer v6 = map.put("Ann", 28);  // 重新设置键为 Ann的,值覆盖,返回覆盖的值
              
              System.out.println(v1);
              System.out.println(v2);
              System.out.println(v3);
              System.out.println(v4);
              System.out.println(v5);
              System.out.println(v6);
              System.out.println(map);
          }
      
      }
      View Code

 

3. Map集合的遍历之  键找值

  • 键找值思路:

    • 获取所有键的集合

    • 遍历键的集合,获取到每一个键

    • 根据键找值

  • 案例演示

    • Map集合的遍历之键找值

    • 图解:
      •  

         

    • package com.heima.map;
      
      import java.util.HashMap;
      import java.util.Iterator;
      import java.util.Map;
      import java.util.Set;
      
      public class Demo2_Iterator {
      
          /**
           Map集合的遍历
               1.通过查看Map集合的api发现没有iterator方法, 那么双列集合如何迭代呢?
               
           */
          public static void main(String[] args) {
              Map<String, Integer> map = new HashMap<String, Integer>();
              map.put("Ann", 23);
              map.put("Bill", 24);
              map.put("Carolle", 25);
              map.put("Dell", 26);
              
      //        Integer i = map.get("Ann");
      //        System.out.println(i);
              
              // 获取所有的键
              /*Set<String> keySet = map.keySet();  // 获取所有键的集合
              Iterator<String> it = keySet.iterator();   // 获取迭代器
              while(it.hasNext()) {  // 判断集合中是否有元素
                  String key = it.next(); //  获取每一个键
                  Integer value = map.get(key);  // 根据键获取值
                  System.out.println(key + "=" + value);
              }*/
              
              
              // 使用增强for循环遍历
              for (String key : map.keySet()) {
                  System.out.println(key + "=" + map.get(key));
              }
              
          }
      
      }
      View Code

 

4. Map集合的遍历之键 值对对象找键和值

  • 键值对对象找键和值思路:

    • 获取所有键值对对象的集合

    • 遍历键值对对象的集合,获取到每一个键值对对象

    • 根据键值对对象找键和值

  • 图解:
    •  

       

  • Set<Map.Entry<K,V>> entrySet()
              返回此映射中包含的映射关系的 Set 视图。
  • 案例演示

    • Map集合的遍历之键值对对象找键和值

    • package com.heima.map;
      
      import java.util.HashMap;
      import java.util.Iterator;
      import java.util.Map;
      import java.util.Set;
      
      public class Demo3_Iterator {
      
          /**
           根据 键值对对象 找键和值思路:
              获取所有键值对对象的集合
              遍历键值对对象的集合,获取到每一个键值对对象
              根据键值对对象找键和值
           */
          public static void main(String[] args) {
              HashMap<String, Integer> hm = new HashMap<>(); 
              hm.put("张三", 23); 
              hm.put("李四", 24); 
              hm.put("王五", 25); 
              hm.put("赵六", 26); 
              
              // Map.Entry 说明Entry是Map的内部接口,将 键和值 封装成了 Entry对象,并存储在Set集合中
              Set<Map.Entry<String, Integer>> entrySet = hm.entrySet(); //获取所有的键值对象的集合 
              Iterator<Map.Entry<String, Integer>> it = entrySet.iterator();//获取迭代器 
              while(it.hasNext()) { 
                  Map.Entry<String, Integer> en = it.next(); //获取键值对对象 
                  String key = en.getKey(); //根据键值对对象获取键 
                  Integer value = en.getValue(); //根据键值对对象获取值 
                  System.out.println(key + "=" + value); 
              }
              
              // 用增强for循环
              for(Map.Entry<String,Integer> en : hm.entrySet()) {
                  System.out.println(en.getKey() + "=" + en.getValue());
              }
          }
      
      }
      View Code 
  • 源码分析
    • 首先从  Map.Entry<String, Integer> en = it.next(); 中看是 父类引用指向子类对象。
      • Map.Entry是接口
      • it.next()中是每个 HashMap对象 或 Map对象。
    • 从Map接口中可以看到 Entry 接口是其内部接口,Entry接口中有getKey和getValue等抽象方法,不能运行,需要子类重写
    • 从HashMap类中,private static class Entry<K,V> extends HashMap.Entry<K,V> {...}
      • static class Entry<K,V> implements Map.Entry<K,V> {...}
      • 重写了getKey和getValue方法
      • Entry是Map.Entry的子类
        • Map.Entry<String, Integer> en = it.next();    // 父类引用指向子类对象
        • Entry<String, Integer> en = it.next();            // 直接获取的是子类对象

 

5. HashMap集合 键是Student,值是String 的案例

  • 案例演示

    • HashMap集合键是Student值是String的案例

    • package com.heima.map;
      
      import java.util.HashMap;
      import java.util.Map;
      
      import com.heima.bean.Student;
      
      
      public class Demo5_HashMap {
      
          /**
           案例演示:
               HashMap集合 键是Student,值是String 的案例
           Key 键: 是学生对象,代表每一个学生
           Value 值: 是字符串对象,代表学生归属地
           */
          public static void main(String[] args) {
              HashMap<Student, String> hm = new HashMap<>();
              hm.put(new Student("Ann",23), "beijing");
              hm.put(new Student("Bill",24), "shanghai");
              hm.put(new Student("Carolle",25), "guangzhou");
              hm.put(new Student("Ann",23), "shenzhen");
              
              for (Map.Entry<Student,String> en : hm.entrySet()) {
                  System.out.println(en);
              }
              
          }
      
      }
      HashMap 键为自定义类Student
      package com.heima.bean;
      
      public class Student {
          private String name;
          private int age;
          
          
          public Student() {
              super();
              
          }
          public Student(String name, int age) {
              super();
              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 String toString() {
              return "Student [name=" + name + ", age=" + age + "]";
          }
          
          // 自定义的对象,在HashMap或HashSet中都要重写 hashCode和equals方法
          @Override
          public int hashCode() {
              final int prime = 31;
              int result = 1;
              result = prime * result + age;
              result = prime * result + ((name == null) ? 0 : name.hashCode());
              return result;
          }
          
          @Override
          public boolean equals(Object obj) {
              if (this == obj)
                  return true;
              if (obj == null)
                  return false;
              if (getClass() != obj.getClass())
                  return false;
              Student other = (Student) obj;
              if (age != other.age)
                  return false;
              if (name == null) {
                  if (other.name != null)
                      return false;
              } else if (!name.equals(other.name))
                  return false;
              return true;
          }
          
          
          
          
          
          
      }
      自定义类Student

       

6. LinkedHashMap的概述和使用

  • 案例演示

    • LinkedHashMap的特点

      • 底层是链表实现的可以保证怎么存就怎么取

    • package com.heima.map;
      
      import java.util.LinkedHashMap;
      import java.util.Map;
      
      public class Demo6_LinkedHashMap {
      
          /**
           LinkedHashMap的特点
               底层是链表实现的可以保证怎么存就怎么取
           */
          public static void main(String[] args) {
              LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>();
              lhm.put("Ann",23);
              lhm.put("Bill",24);
              lhm.put("Carolle",25);
              lhm.put("Dell",26);
              
              for (Map.Entry<String, Integer> en : lhm.entrySet()) {
                  System.out.println(en);
              }
              
              
          }
      
      }
      View Code

       

7. TreeMap集合 键是Student,值是String的案例

  • 案例演示

    • TreeMap集合键是Student值是String的案例

    • package com.heima.map;
      
      import java.util.Comparator;
      import java.util.Map;
      import java.util.TreeMap;
      
      import com.heima.bean.Student;
      
      public class Demo7_TreeMap {
      
          /**
           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.getAge() - s2.getAge();
                      return num == 0 ? s1.getName().compareTo(s2.getName()) : num ;
                  }
              });
              tm.put(new Student("Ann",23), "beijing");
              tm.put(new Student("Bill",24), "shanghai");
              tm.put(new Student("Carolle",25), "guangzhou");
              tm.put(new Student("Ann",23), "shenzhen");
              
              for (Map.Entry<Student, String> en : tm.entrySet()) {
                  System.out.println(en);
              }
              
          }
      
          public static void demo1() {
              TreeMap<Student, String> tm = new TreeMap<>();
              tm.put(new Student("Ann",23), "beijing");
              tm.put(new Student("Bill",24), "shanghai");
              tm.put(new Student("Carolle",25), "guangzhou");
              tm.put(new Student("Ann",23), "shenzhen");
              
              System.out.println(tm);
              for (Map.Entry<Student, String> en : tm.entrySet()) {
                  System.out.println(en);
              }
          }
      
      }
      View Code
      package com.heima.bean;
      
      public class Student implements Comparable<Student> {
          private String name;
          private int age;
          
          
          public Student() {
              super();
              
          }
          public Student(String name, int age) {
              super();
              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 String toString() {
              return "Student [name=" + name + ", age=" + age + "]";
          }
          
          // 自定义的对象,在HashMap或HashSet中都要重写 hashCode和equals方法
          @Override
          public int hashCode() {
              final int prime = 31;
              int result = 1;
              result = prime * result + age;
              result = prime * result + ((name == null) ? 0 : name.hashCode());
              return result;
          }
          
          @Override
          public boolean equals(Object obj) {
              if (this == obj)
                  return true;
              if (obj == null)
                  return false;
              if (getClass() != obj.getClass())
                  return false;
              Student other = (Student) obj;
              if (age != other.age)
                  return false;
              if (name == null) {
                  if (other.name != null)
                      return false;
              } else if (!name.equals(other.name))
                  return false;
              return true;
          }
          
          // 自定义的对象,在TreeMap或TreeSet中都要继承Comparable接口后,重写compareTo方法
          @Override
          public int compareTo(Student s) {
              int num = this.age - s.age;
              return num == 0 ? this.name.compareTo(s.name) : num;
          }
          
          
          
          
          
          
          
          
      }
      Student类

       

 

8. 统计字符串中每个字符出现的次数

  • 案例演示

    • 需求:统计字符串中每个字符出现的次数

    • package com.heima.test;
      
      import java.util.HashMap;
      
      public class Test1 {
      
          /**
           需求:统计字符串中每个字符出现的次数
           分析:
               1. 定义一个需要被统计字符的字符串
               2. 将字符串转换为字符数组
               3. 定义双列集合,存储字符串中字符以及字符出现的次数
               4. 遍历字符数组获取每一个字符,并将字符存储在双列集合中
               5. 存储过程中要做判断,如果集合中不包含这个键,将就该字符当做键,值为1存储,如果集合中包含这个键,就将值+1存储。
               6. 打印双列集合,获取字符出现的次数
           */
          public static void main(String[] args) {
              String s = "aaacccccdhangagainaiognaignaiaijaijga";
              char[] arr = s.toCharArray();
              
              // 没有特殊需求,都默认用HashMap,因为HashMap效率最高
              HashMap<Character, Integer> hm = new HashMap<>();
              for (char c : arr) {
                  /*if(!hm.containsKey(c)) {
                      hm.put(c, 1);                
                  } else {
                      hm.put(c,hm.get(c)+1);
                  }*/
                  hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1);
              }
              
              for (Character key : hm.keySet()) {
                  System.out.println(key + "--" +hm.get(key));
              }
          }
      
      }
      View Code

       

9. 集合嵌套之HashMap嵌套HashMap

  • 案例演示

    • 集合嵌套之HashMap嵌套HashMap

    • package com.heima.map;
      
      import java.util.HashMap;
      
      import com.heima.bean.Student;
      
      public class Demo8_HashMapHashMap {
      
          /**
          集合嵌套之HashMap嵌套HashMap
           */
          public static void main(String[] args) {
              // 一班
              HashMap<Student, String> hm1 = new HashMap<>();
              hm1.put(new Student("Ann",23), "北京");
              hm1.put(new Student("Bill",24), "上海");
              hm1.put(new Student("Carolle",25), "深圳");
              hm1.put(new Student("Dell",26), "广州");
              
              // 二班
              HashMap<Student, String> hm2 = new HashMap<>();
              hm2.put(new Student("Elle",23), "北京");
              hm2.put(new Student("Mary",24), "上海");
              hm2.put(new Student("Joe",25), "深圳");
              hm2.put(new Student("Jane",26), "广州");
              
              //定义第一层HashMap
              HashMap<String, HashMap<Student, String>> hm = new HashMap<>();
              hm.put("一班", hm1);
              hm.put("二班", hm2);
              
              
              for (String string : hm.keySet()) {
                  System.out.println(string);
                  for (Student s : hm.get(string).keySet()) {
                      System.out.println(s);
                  }
              }
          }
      
      }
      View Code

       

 

10. HashMap和Hashtable的区别

  • 面试题

    • HashMap和Hashtable的区别

      • Hashtable是JDK1.0版本出现的,是线程安全的,效率低,HashMap是JDK1.2版本出现的,是线程不安全的,效率高

      • Hashtable不可以存储null键和null值,HashMap可以存储null键和null值

  • 案例演示

    • HashMap和Hashtable的区别

    • package com.heima.map;
      
      import java.util.HashMap;
      import java.util.Hashtable;
      
      public class Demo9_Hashtable {
      
          /**
           HashMap和Hashtable的区别:
           共同点:
               底层都是Hash算法,都是双列集合
           区别:
               1. HashMap是线程不安全的,效率高,JDK1.2版本
                   Hashtable线程安全的,效率低,JDK1.0版本
               2. HashMap可以存储null键,null值
                   Hashtable不可以存储null键,null值
           */
          public static void main(String[] args) {
              // 创建HashMap
              HashMap<String, Integer> hm = new HashMap<>();
              hm.put(null, 23);
              hm.put("Car",null)
              System.out.println(hm);
              
              // 创建Hashtable
              Hashtable<String, Integer> ht = new Hashtable<>();
              //ht.put(null,11);  // 报错NullPointerException
              
              
          }
      
      }
      View Code

       

 

11. Collections工具类的概述和常见方法讲解

  • Collections类概述

    • 针对集合操作 的工具类

    • 当类中的所有成员方法都是静态的,那么会自动私有该类,避免实例化该类,直接使用 类名.成员方法 调用即可
  • Collections成员方法

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

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

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

    • public static void reverse(List<?> list)

    • public static void shuffle(List<?> list)

    • package com.heima.collections;
      
      import java.util.ArrayList;
      import java.util.Collections;
      
      public class Demo1_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)  随机置换
           */
          public static void main(String[] args) {
      //        demo1();
      //        demo2();
      //        demo3();
      //        demo4();
              ArrayList<String> list = new ArrayList<>();
              list.add("a");
              list.add("c");
              list.add("d");
              list.add("g");
              
              Collections.shuffle(list);  // 随机置换,可以用来洗牌
              System.out.println(list);
          }
      
          public static void demo4() {
              ArrayList<String> list = new ArrayList<>();
              list.add("a");
              list.add("c");
              list.add("d");
              list.add("g");
              
              
              Collections.reverse(list);
              System.out.println(list);
          }
      
          public static void demo3() {
              ArrayList<String> list = new ArrayList<>();
              list.add("a");
              list.add("c");
              list.add("d");
              list.add("g");
              
              System.out.println(Collections.max(list));
          }
      
          public static void demo2() {
              ArrayList<String> list = new ArrayList<>();
              list.add("a");
              list.add("c");
              list.add("d");
              list.add("g");
              
              // 二分查找,返回查找值的索引值
              System.out.println(Collections.binarySearch(list, "d"));
          
              // 查找不存在的值,返回-2
              // 如果搜索键包含在列表中,则返回搜索键的索引;
              // 否则返回 (-(插入点) - 1)。插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都小于指定的键,则为 list.size()。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。 
              System.out.println(Collections.binarySearch(list, "b"));
          }
      
          public static void demo1() {
              ArrayList<String> list = new ArrayList<>();
              list.add("b");
              list.add("c");
              list.add("d");
              list.add("a");
              System.out.println(list);
              
              
              // 将集合排序
              Collections.sort(list);
              System.out.println(list);
          }
      
      }
      View Code

       

 

12. 模拟斗地主洗牌和发牌

  • 案例演示

    • 模拟斗地主洗牌和发牌,牌没有排序

    • package com.heima.test;
      
      import java.util.ArrayList;
      import java.util.Collections;
      
      public class Test2 {
          /*
           需求:模拟斗地主洗牌和发牌,牌没有排序
           分析:
           1. 买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
           2. 洗牌
           3. 发牌
           4. 看牌
           */
          public static void main(String[] args) {
              // 买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
              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("小王");
              
              /*System.out.println(poker);
              System.out.println(poker.size());*/
              
              // 洗牌
              Collections.shuffle(poker);
              
              // 发牌,给三个玩家发牌
              ArrayList<String> player1 = new ArrayList<>();
              ArrayList<String> player2 = new ArrayList<>();
              ArrayList<String> player3 = new ArrayList<>();
              ArrayList<String> bottom = new ArrayList<>();  // 底牌
              
              for (int i = 0; i < poker.size(); i++) {
                  if(i >= poker.size() - 3) {
                      bottom.add(poker.get(i));
                  } else if (i % 3 == 0) {
                      player1.add(poker.get(i));    
                  } else if (i % 3 == 1) {
                      player2.add(poker.get(i));
                  } else {
                      player3.add(poker.get(i));
                  }
              }
              
              // 看牌
              System.out.println(player1);
              System.out.println(player2);
              System.out.println(player3);
              System.out.println(bottom);
              
          }
      }
      View Code

       

 

13. 模拟斗地主洗牌和发牌并对牌进行排序的原理图解

  • 画图演示

    • 画图说明排序原理

    •  

       

 

14. 模拟斗地主洗牌和发牌并对牌进行排序的代码实现

  • 案例演示

    • 模拟斗地主洗牌和发牌并对牌进行排序的代码实现

    • package com.heima.test;
      
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.HashMap;
      import java.util.TreeSet;
      
      public class Test3 {
          /*
           需求:模拟斗地主洗牌和发牌,牌没有排序
           分析:
           1. 买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
           2. 洗牌
           3. 发牌
           4. 看牌:有排序功能,理牌
           */
          public static void main(String[] args) {
              // 买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
                      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;
                      
                      // 拼接扑克牌,并将索引和扑克牌存储在HashMap中
                      for (String s1 : num) {
                          for (String s2 : color) {
                              hm.put(index, s2.concat(s1));
                              list.add(index);
                              index++;
                          }
                      }
                      
                      hm.put(index,"小王");
                      list.add(index);
                      index++;
                      hm.put(index,"大王");
                      list.add(index);
                      
                      /*System.out.println(index);
                      System.out.println(hm );
                      System.out.println(list);
                      */
                      // 洗牌
                      Collections.shuffle(list);
                      
                      // 发牌,给三个玩家发牌
                      TreeSet<Integer> player1 = new TreeSet<>();
                      TreeSet<Integer> player2 = new TreeSet<>();
                      TreeSet<Integer> player3 = new TreeSet<>();
                      TreeSet<Integer> bottom = new TreeSet<>();  // 底牌
                      
                      for (int i = 0; i < list.size(); i++) {
                          if(i >= list.size() - 3) {
                              bottom.add(list.get(i));
                          } else if( i % 3 == 0) {
                              player1.add(list.get(i));
                          } else if(i % 3 == 1) {
                              player2.add(list.get(i));
                          } else {
                              player3.add(list.get(i));
                          }
                      }
                      
                                      
                      // 看牌
                      lookPoker(hm,player1,"高进");
                      lookPoker(hm,player2,"张三");
                      lookPoker(hm,player3,"王五");
                      lookPoker(hm,bottom,"底牌");
                      
          }
          
          /*
           * 看牌
           * 返回值类型:void
           * 参数列表:HashMap,TreeSet,String name
           */
          public static void lookPoker(HashMap<Integer, String> hm, TreeSet<Integer> ts, String name) {
              System.out.print(name + "的牌是:");
              for (Integer i : ts) {
                  System.out.print(hm.get(i) + " ");
              }
              System.out.println();
          }
      }
      View Code

 

15. 泛型固定下边界

  • ? super E

  • package com.heima.collections;
    
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.TreeSet;
    
    import com.heima.bean.BaseStudent;
    import com.heima.bean.Student;
    
    public class Demo2_Genric {
    
        /**
         * ? super E 泛型固定下边界
         * ? extends E 泛型固定下边界
         */
        public static void main(String[] args) {
    //        demo1();
            
            /* 泛型固定下边界
             * TreeSet(Comparator<? super E> comparator) 
                      构造一个新的空 TreeSet,它根据指定比较器进行排序。
               * TreeMap(Comparator<? super K> comparator) 
                      构造一个新的、空的树映射,该映射根据给定比较器进行排序
             */
            TreeSet<Student> ts1 = new TreeSet<>(new CompareByAge());
            ts1.add(new Student("张三",23));
            ts1.add(new Student("李四",24));
            ts1.add(new Student("王五",25));
            ts1.add(new Student("赵六",26));
            
            System.out.println(ts1);
            
            TreeSet<BaseStudent> ts2 = new TreeSet<>(new CompareByAge());
            ts2.add(new BaseStudent("张三",23));
            ts2.add(new BaseStudent("李四",24));
            ts2.add(new BaseStudent("王五",25));
            ts2.add(new BaseStudent("赵六",26));
            
            System.out.println(ts2);  // CompareByAge里面的泛型是Student,这里BaseStudent也能使用
            // 可以实现的原因在于TreeSet 或TreeMap的构造方法中的 泛型固定下边界
            
            
            
            
            
            
        }
    
        public static void demo1() {
            ArrayList<Student> list1 = new ArrayList<>();
            ArrayList<BaseStudent> list2 = new ArrayList<>();
             
            list1.add(new Student("Ann",23));
            list1.add(new Student("Bill",24));
            
            list2.add(new BaseStudent("张三",25));
            list2.add(new BaseStudent("李四",26));
            
            list1.addAll(list2);  // 固定上边界 ? extends Student;?是Student的子类
            System.out.println(list1);
        }
    
    }
    
    class CompareByAge implements 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;
        }
        
    }
    View Code
  • package com.heima.bean;
    
    public class Student implements Comparable<Student> {
        private String name;
        private int age;
        
        
        public Student() {
            super();
            
        }
        public Student(String name, int age) {
            super();
            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 String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }
        
        // 自定义的对象,在HashMap或HashSet中都要重写 hashCode和equals方法
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Student other = (Student) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
        
        // 自定义的对象,在TreeMap或TreeSet中都要继承Comparable接口后,重写compareTo方法
        @Override
        public int compareTo(Student s) {
            int num = this.age - s.age;
            return num == 0 ? this.name.compareTo(s.name) : num;
        }
        
        
        
        
        
        
        
        
    }
    Student类
  • package com.heima.bean;
    
    public class BaseStudent extends Student {
    
        public BaseStudent() {
            super();
            
        }
    
        public BaseStudent(String name, int age) {
            super(name, age);
            
        }
        
    }
    BaseStudent类

     

 

 

posted on 2020-06-03 09:56  Zoe233  阅读(190)  评论(0)    收藏  举报