zoukankan      html  css  js  c++  java
  • 集合(Map、Collections)【4】

    集合

    Map

    1.1 Map集合概述

    • Interface Map<K,V> K:键的类型;V:值的类型

    • 将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值

    • 举例:学生的学号和姓名

      lang10001 张三

      lang10002 李四

      lang10003 王五

    创建Map集合的对象

    • 多态的方式

    • 具体的实现类HashMap

    public class MapDemo01 {
        public static void main(String[] args) {
            //创建集合对象
            Map<String,String> map = new HashMap<>();
    ​
            //将指定的值与该映射中的指定键相关联
            map.put("lang10001","张三");
            map.put("lang10002","李四");
            map.put("lang10003","王五");
            map.put("lang10003","李六");
    ​
            //输出集合对象
            System.out.println(map);
        }
    }

    1.2 Map集合的基本功能

    public class MapDemo02 {
        public static void main(String[] args) {
            //创建集合对象
            Map<String,String> map = new HashMap<>();
    ​
            //添加元素
            map.put("张无忌","赵敏");
            map.put("郭靖","黄蓉");
            map.put("杨过","小龙女");
    ​
            //remove 根据键删除键值对元素
            System.out.println(map.remove("郭靖"));
            System.out.println(map.remove("李四"));//没有的返回null
    //clear: 清除所有的键值对元素
            //map.clear();//谨慎使用
    //containsKey :判断集合是否包含指定的键
            System.out.println(map.containsKey("郭靖"));
            System.out.println(map.containsKey("张无忌"));
    ​
            //containsValue: 判断集合是否为空
            System.out.println(map.containsValue("赵敏"));
            System.out.println(map.containsValue("黄蓉"));
    ​
            //isEmpty : 判断集合是否为空
            System.out.println(map.isEmpty());
    ​
            //size:获取集合的长度
            System.out.println(map.size());
            
            //打印集合
            System.out.println(map);
        }
    }

    1.3 Map集合的获取功能

    public class MapDemo03 {
        public static void main(String[] args) {
            //创建集合对象
            Map<String,String> map = new HashMap<>();
    ​
            //添加元素
            map.put("张无忌","赵敏");
            map.put("郭靖","黄蓉");
            map.put("杨过","小龙女");
    ​
            //get() :根据键获取值
            System.out.println(map.get("张无忌"));
            System.out.println(map.get("太乙真人"));
    ​
            //Set<K> keySet() :获取所有键的集合
            Set<String> keySet = map.keySet();
            for (String key : keySet){
                System.out.println(key);
            }
    ​
            //Collection<V> :获取所有值的集合
            Collection<String> values = map.values();
            for (String s : values){
                System.out.println(s);
            }
    ​
            //Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
            Set<Map.Entry<String,String>> entrySet = map.entrySet();
            for (Map.Entry<String,String> s : entrySet){
                System.out.println(s);
            }
        }
    }

    1.4 Map 集合的遍历(方式1)

    我们刚才存储的元素是成对出现的,所以我们把map看成是一个夫妻对的集合

    遍历思路:

    • 把所有的丈夫集合起来

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

    • 根据丈夫去找对应的妻子

    转换Map集合中的操作:

    • 获取所有键的集合。用keySet()方法实现

    • 遍历键的集合,获取到每一个键,用增强for实现

    • 根据键去找值。用get(Object key)方法实现

    public class MapDemo {
        public static void main(String[] args) {
            //创建集合对象
            Map<String,String> map = new HashMap<>();
    ​
            //添加元素
            map.put("张无忌","赵敏");
            map.put("郭靖","黄蓉");
            map.put("杨过","小龙女");
    ​
            //获取所有键的集合,用keySet()方法实现
            Set<String> keySet = map.keySet();
            //遍历所有键的集合,获取到每一个键,用增强for
            for (String key:keySet){
                //根据键去找值,用get方法实现
                String value = map.get(key);
                System.out.println(key + "," + value);
            }
        }
    }

    1.5 Map 集合遍历(方法2)

    我们刚才存储的元素是成对出现的,所以我们把map看成是一个夫妻对的集合

    遍历思路:

    • 获取所有结婚证的集合

    • 遍历结婚证的集合,得到每一个结婚证

    • 根据结婚证获取丈夫和妻子

    转换为Map集合中的操作:

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

      Set<Map.Entry<K,V>> entrySet(): 获取所有键值对对象的集合

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

      用增强for实现,得到每一个Map.Entry

    • 根据键值对对象获取键和值

      getKey() 得到键

      getValue()得到值

    public class MapDemo02 {
        public static void main(String[] args) {
            //创建集合对象
            Map<String,String> map = new HashMap<>();
    ​
            //添加元素
            map.put("张无忌","赵敏");
            map.put("郭靖","黄蓉");
            map.put("杨过","小龙女");
    ​
            //获取所有键值对对象的集合
            Set<Map.Entry<String,String>> entrySet = map.entrySet();
            for (Map.Entry<String,String> me : entrySet){
                System.out.println(me.getKey()+","+me.getValue());
            }
        }
    }

    案例:HashMap集合存储学生对象并遍历

    需求:创建一个HashMap集合,键是学号(String),值是学生对象(Student)。存储三个键值对元素,并遍历

    思路:

    ① 定义学生类

    ② 创建HashMap集合对象

    ③ 创建学生对象

    ④ 把学生添加到集合

    ⑤ 遍历集合

    方式1:键找值

    方式2:键值对对象找键和值

    学生类

    public class Student {
        private String name;
        private int 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;
        }
    ​
        public Student() {
        }
    ​
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    ​

     

    测试类

    public class HashMapDemo {
        public static void main(String[] args) {
            //创建一个HashMap集合对象
            HashMap<String,Student> hm = new HashMap<>();
    ​
            //创建学生对象
            Student s1 = new Student("张三",20);
            Student s2 = new Student("李四",22);
            Student s3 = new Student("王五",24);
    ​
            //把学生添加到集合
            hm.put("lang10001",s1);
            hm.put("lang10002",s2);
            hm.put("lang10003",s3);
    ​
            //方式1:键找值
            Set<String> keySet = hm.keySet();
            for (String key : keySet){
                Student value = hm.get(key);
                System.out.println(key + "," + value.getName() + "," + value.getAge());
            }
    ​
            //方式2: 键值对对象找键和值
            Set<Map.Entry<String,Student>> entrySet = hm.entrySet();
            for (Map.Entry<String,Student> m : entrySet){
                String key = m.getKey();
                Student s = m.getValue();
                System.out.println(key + "," +s.getName() + "," + s.getAge());
            }
        }
    案例: HashMap集合存储学生对象并遍历

    需求:创建一个HashMap集合,键是学生对象(Student),值是居住地(String)。存储多个键值对元素,并遍历。

    要求:保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象

    思路:

    ① 定义学生类

    ② 创建HashMap集合对象

    ③ 创建学生对象

    ④ 把学生添加到集合

    ⑤ 遍历集合

    ⑥ 在学生类中重写两个方法

    hashCode()

    equals()

    学生类

    public class Student {
        private String name;
        private int 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;
        }
    ​
        public Student() {
        }
    ​
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    ​
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    ​
            Student student = (Student) o;
    ​
            if (age != student.age) return false;
            return name != null ? name.equals(student.name) : student.name == null;
        }
    ​
        @Override
        public int hashCode() {
            int result = name != null ? name.hashCode() : 0;
            result = 31 * result + age;
            return result;
        }
    }

     

    测试类

    public class HashMapDemo {
        public static void main(String[] args) {
            //创建HashMap集合对象
            HashMap<Student,String> hm = new HashMap<>();
    ​
            //创建学生对象
            //创建学生对象
            Student s1 = new Student("张三",20);
            Student s2 = new Student("李四",22);
            Student s3 = new Student("王五",24);
            Student s4 = new Student("王五",24);
    ​
            //把学生对象添加到集合
            hm.put(s1,"山东省济南");
            hm.put(s2,"河北省北京");
            hm.put(s3,"广东省广州");
            hm.put(s4,"四川省成都");
    ​
            //遍历集合
            Set<Student> keySet = hm.keySet();
            for (Student s : keySet){
                String value = hm.get(s);
                System.out.println(s.getName()+","+s.getAge()+"," +value);
            }
    ​
        }
    }

    案例:ArrayList集合存储HashMap元素并遍历

    需求:创建一个ArrayList集合,存储三个元素,每个元素都是HashMap,每个HashMap的键和值都是String,并遍历

    思路:

    ① 创建ArrayList集合

    ② 创建hashMap集合,并添加键值对元素

    ③ 把HashMap作为元素添加到ArrayList集合

    ④ 遍历ArrayList集合

    public class ArrayListIncludeHashMapDemo {
        public static void main(String[] args) {
            //创建ArrayList集合
            ArrayList<HashMap<String,String>> array = new ArrayList<>();
    ​
            //创建HashMap集合,并添加键值对元素
            HashMap<String,String> hm1 = new HashMap<>();
            hm1.put("孙策","大乔");
            hm1.put("周瑜","小乔");
            array.add(hm1);
    ​
            HashMap<String,String> hm2 = new HashMap<>();
            hm1.put("郭靖","黄蓉");
            hm1.put("杨过","小龙女");
            array.add(hm2);
    ​
            HashMap<String,String> hm3 = new HashMap<>();
            hm1.put("令狐冲","任盈盈");
            hm1.put("林平之","岳灵珊");
            array.add(hm3);
            
            for(HashMap<String,String> h : array){
                Set<String> keySet = h.keySet();
                for (String key:keySet){
                    String value = h.get(key);
                    System.out.println(key +","+ value);
                }
            }
    ​
        }
    }

    案例:HashMap集合存储ArrayList元素并遍历

    需求:创建一个HashMap 集合,存储三个键值对元素,每个键值对元素的键是String,值是ArrayList,每个ArrayList的元素是String,并遍历

    思路:

    ① 创建HashMap集合

    ② 创建ArrayList集合,并添加元素

    ③ 把ArrayList作为元素添加到HashMap集合

    ④ 遍历HashMap集合

    public class HashMapIncludeArrayListDemo {
        public static void main(String[] args) {
            //创建HashMap集合
            HashMap<String, ArrayList<String>> hm = new HashMap<>();
    ​
            //创建ArrayList集合,并添加元素
            ArrayList<String> a1 = new ArrayList<>();
            a1.add("曹操");
            a1.add("许褚");
            a1.add("赵云");
            hm.put("三国演义",a1);
    ​
            ArrayList<String> a2 = new ArrayList<>();
            a1.add("孙悟空");
            a1.add("猪八戒");
            a1.add("沙和尚");
            hm.put("西游记",a2);
    ​
            ArrayList<String> a3 = new ArrayList<>();
            a1.add("宋江");
            a1.add("林冲");
            a1.add("李逵");
            hm.put("水浒传",a3);
    ​
            //遍历HashMap集合
            Set<String> keySet = hm.keySet();
            for (String key : keySet){
                System.out.println(key);
                ArrayList<String> value = hm.get(key);
                for (String s : value){
                    System.out.println("	"+s);
                }
            }
        }
    }
    ​

    案例:统计字符串中每个字符出现的次数

    需求:键盘录入一个字符串,要求统计字符串中每个字符串出现的次数。

    举例:键盘录入“aabbacbacabdedea” 在控制台中输出:“a(6)b(4)c(1)d(2)e(2)”

    思路:

    ① 键盘录入一个字符串

    ② 创建HashMap集合,键是Character,值是Integer

    ③ 遍历字符串,得到每一个字符

    ④ 拿得到的每一个字符作为键到HashMap集合中去找对应的值,看其返回值

    如果返回值是null:说明该字符在HashMap集合中不存在,就把该字符作为键,1作为值存储

    如果返回值不是null:说明该字符在HashMap集合中存在,把该值加1,然后重新存储该字符和对应的值

    ⑤ 遍历HashMap集合,得到键和值,按照要求进行拼接

    public class HashMapDemo {
        public static void main(String[] args) {
            //从键盘录入一个字符串
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入一个字符串:");
            String line = sc.nextLine();
    ​
            //创建一个HashMap集合,键是Character,值是Integer
            //HashMap<Character,Integer> hm = new HashMap<>();
            TreeMap<Character,Integer> hm = new TreeMap<>();
    ​
            //遍历字符串,得到每一个字符
            for (int i = 0 ; i <line.length();i++){
                char key = line.charAt(i);
                //拿得到的每一个字符作为键到HashMap集合中去找对应的值,看起返回值
                Integer value = hm.get(key);
    ​
                if (value == null){
                    hm.put(key,1);
                }else {
                    value++;
                    hm.put(key,value);
                }
            }
    ​
            //遍历HashMap集合,得到键和值,按照要求进行拼接
            StringBuilder sb = new StringBuilder();
    ​
            Set<Character> keySet = hm.keySet();
            for (Character key : keySet){
                Integer value = hm.get(key);
                sb.append(key).append("(").append(value).append(")");
            }
    ​
            String result = sb.toString();
            System.out.println(result);
        }
    }

    Collections

    1.1 Collections概述和使用

    Collections类的概述

    • 是针对集合操作的工具类

    Collections类的常用方法

    • public static <T extends Comparable<? super T>> void sort(List<T> list):将制定的列表按升序排序

    • public static void reverse(List<?> list):反转指定列表中元素的顺序

    • public static void shuffle(List <?> list):使用默认的随机源随机排列指定的列表

    public class CollectionsDemo01 {
        public static void main(String[] args) {
            //创建集合对象
            List<Integer> list = new ArrayList<>();
    ​
            //添加元素
            list.add(30);
            list.add(24);
            list.add(79);
            list.add(42);
            list.add(70);
    ​
            //将制定的列表按升序排序
            //Collections.sort(list);
    //反转指定列表中元素的顺序
           // Collections.reverse(list);
    //使用默认的随机源随机排列指定的列表
            Collections.shuffle(list);
    ​
            System.out.println(list);
        }
    }

    案例:ArrayList存储学生对象并排序

    需求:ArrayList存储学生对象,使用Collections对ArrayList进行排序

    要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

    思路:

    ① 定义学生类

    ② 创建ArrayList集合对象

    ③ 创建学生对象

    ④ 把学生对象添加到集合

    ⑤ 使用Collections对ArrayList集合排序

    ⑥遍历集合

    学生实体类

    public class Student {
        private String name;
        private int 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;
        }
    ​
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    ​
        public Student() {
        }
    }

     

    测试类

    public class CollectionsDemo {
        public static void main(String[] args) {
            //创建一个ArrayList集合对象
            ArrayList<Student> array = new ArrayList<>();
    ​
            //创建学生对象
            Student s1 = new Student("zhangsan",20);
            Student s2 = new Student("lisi",23);
            Student s3 = new Student("wangwu",21);
            Student s4 = new Student("piziliu",20);
    ​
            //添加到集合中
            array.add(s1);
            array.add(s2);
            array.add(s3);
            array.add(s4);
    ​
            //使用Collections对ArrayList集合排序
            //sort(List<T>,Comparator<? super T>)
            Collections.sort(array, new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    //按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
                    int num = o1.getAge()-o2.getAge();
                    int num2 = num==0?o1.getName().compareTo(o2.getName()):num;
                    return num2;
                }
    ​
            });
    ​
            //遍历集合
            for(Student s : array){
                System.out.println(s.getName()+","+s.getAge());
            }
    ​
        }
    }

    案例;模拟斗地主

    需求:通过程序实现斗地主过程中的洗牌,发牌和看牌

    思路:

    ① 创建一个牌盒,也就是定义一个集合对象,用ArrayList集合实现

    ②往牌盒里面装牌

    ③ 洗牌,也就是把牌打散,用Collections的shuffle()方法实现

    ④ 发牌,也就是遍历集合,给三个玩家发牌

    ⑤ 看牌,就是有三个玩家分别遍历自己的牌

    public class PokerDemo {
        public static void main(String[] args) {
            //创建一个牌盒,即定义一个ArrayList集合对象
            ArrayList<String> array = new ArrayList<>();
    ​
            //往牌盒李装牌
            /*
                ♦2。。。。
                ♠2。。。。
                ♥2。。。。
                ♣2。。。。
                大王,小王
            */
            //定义花色数组
            String[] colors = {"♦","♠","♥","♣"};
            //定义点数数组
            String[] numbers = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
            for (String color : colors){
                for (String number : numbers){
                    array.add(color+number);
                }
            }
            array.add("大王");
            array.add("小王");
    ​
            //洗牌,也就是把牌打散,用Collections的shuffle()方法实现
            Collections.shuffle(array);
    ​
            //发牌,也就是遍历集合,给三个玩家发牌
            ArrayList<String> w1 = new ArrayList<>();
            ArrayList<String> w2 = new ArrayList<>();
            ArrayList<String> w3 = new ArrayList<>();
            ArrayList<String> dpArray = new ArrayList<>();
    ​
            for (int i=0;i<array.size();i++){
                String poker = array.get(i);
                if (i>=array.size()-3){
                    dpArray.add(poker);
                }else if (i%3==0){
                    w1.add(poker);
                }else if (i%3==1){
                    w2.add(poker);
                }else if (i%3==2){
                    w3.add(poker);
                }
            }
    ​
            //看牌,就是有三个玩家分别遍历自己的牌
            lookPoker("张三",w1);
            lookPoker("李四",w2);
            lookPoker("王五",w3);
            lookPoker("底牌",dpArray);
            //System.out.println(array);
        }
    ​
        //看牌的方法
        public static void lookPoker(String name, ArrayList<String> array){
            System.out.println(name + "的牌是:");
            for (String poker : array){
                System.out.print(poker+" ");
            }
            System.out.println();
        }
    }

    案例:模拟斗地主升级版

    需求:通过程序实现斗地主过程中的洗牌,发牌和看牌

    要求:对牌进行排序

    思路:

    ① 创建HashMap,键是编号

    ② 创建ArrayList,存储编号

    ③ 创建花色数组和点数数组

    ④ 从0开始往HashMap里面存储编号,并存储对应的牌。同时往ArrayList里面存储编号

    ⑤ 洗牌(洗的是编号),用Collections的shuffle()方法实现

    ⑥ 发牌(发的也是编号,为了保证编号是排序的,创建TreeSet集合接收)

    ⑦ 定义方法看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)

    ⑧ 调用看牌方法

    public class PokerDemo {
        public static void main(String[] args) {
           //创建HashMap,键是编号,值是牌
            HashMap<Integer,String> hm = new HashMap<>();
    ​
            //创建ArrayList,存储编号
            ArrayList<Integer> array =  new ArrayList<>();
    ​
            //定义花色数组
            String[] colors = {"♦","♠","♥","♣"};
            //定义点数数组
            String[] numbers = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
    ​
            //从0开始往HashMap里面存储编号,并存储对应的牌,同时往ArrayList里面存储编号
            int index = 0;
    ​
            for (String number : numbers){
                for (String color : colors){
                    hm.put(index,color+number);
                    array.add(index);
                    index++;
                }
            }
            hm.put(index,"小王");
            array.add(index);
            index++;
            hm.put(index,"大王");
            array.add(index);
    ​
            //洗牌
            Collections.shuffle(array);
    ​
            //发牌
            TreeSet<Integer> w1 = new TreeSet<>();
            TreeSet<Integer> w2 = new TreeSet<>();
            TreeSet<Integer> w3 = new TreeSet<>();
            TreeSet<Integer> dpSet = new TreeSet<>();
    ​
            for (int i = 0; i<array.size();i++){
                int x =array.get(i);
                if (i>=array.size()-3){
                    dpSet.add(x);
                }else if (i%3==0){
                    w1.add(x);
                }else if (i%3==1){
                    w2.add(x);
                }else if (i%3==2){
                    w3.add(x);
                }
            }
    ​
            //调用看牌
            lookPoker("张三",w1,hm);
            lookPoker("李四",w2,hm);
            lookPoker("王五",w3,hm);
            lookPoker("底牌",dpSet,hm);
        }
    ​
        //定义方法看牌
        public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer,String> hm){
            System.out.println(name+"的牌是:");
            for (Integer key : ts){
                String poker = hm.get(key);
                System.out.print(poker+" ");
            }
            System.out.println();
        }
    }

     

  • 相关阅读:
    第二十九课 循环链表的实现
    第二十八课 再论智能指针(下)
    第二十七课 再论智能指针(上)
    第二十六课 典型问题分析(Bugfix)
    普通new和placement new的重载
    leetcode 581. Shortest Unsorted Continuous Subarray
    leetcode 605. Can Place Flowers
    leetcode 219. Contains Duplicate II
    leetcode 283. Move Zeroes
    leetcode 217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/DiaoStudy/p/13661635.html
Copyright © 2011-2022 走看看