• 【JAVA基础】19 Map集合


    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类

     

     

  • 相关阅读:
    Excel宏开发之合并单元格
    excel破解工作簿与工作表保护
    jquery高级编程学习
    Git 和 SVN 存储方式的差异对比
    SSH 连接时间超时
    linux 使用 Python 画图工具matplotlib 提示display 错误
    centos安装字体
    linux编译安装中configure、make和make install各自的作用
    npm run build
    centos ssh 免密码登录
  • 原文地址:https://www.cnblogs.com/zoe233/p/12970232.html
Copyright © 2020-2023  润新知