zoukankan      html  css  js  c++  java
  • 重踏学习Java路上_Day18(Map,Collections)

    1:Map(掌握)
      (1)Map接口概述
          将键映射到值的对象
          一个映射不能包含重复的键
          每个键最多只能映射到一个值

      (2)Map接口和Collection接口的不同
          Map是双列的,Collection是单列的
          Map的键唯一,Collection的子体系Set是唯一的
          Map集合的数据结构值针对键有效,跟值无关
            Collection集合的数据结构是针对元素有效
         (3)Map接口功能概述
      A:添加功能
              V put(K key,V value):添加元素。HashSet与TreeSet也是存在Map的key中,所以key是唯一的,set正是利用了这个特点
                  如果键是第一次存储,就直接存储元素,返回null
                 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
      B:删除功能
              void clear():移除所有的键值对元素
              V remove(Object key):根据键删除键值对元素,并把值返回
      C:判断功能
              boolean containsKey(Object key):判断集合是否包含指定的键
              boolean containsValue(Object value):判断集合是否包含指定的值
              boolean isEmpty():判断集合是否为空
      D:获取功能
              Set<Map.Entry<K,V>>  entrySet()   : Map.Entry 是一个接口,他的用途是表示一个映射项(里面有Key和Value,同时获取一对的key--value,不是单一获取),而Set<Map.Entry<K,V>>表示一个映射项的Set。Map.Entry接口表示一对键值夫妻组合同时获取,而不是单一获取,他是通过迭代的方法来进行获取一对的键值对
              V get(Object key):根据键获取值
              Set<K> keySet():获取集合中所有键的集合
              Collection<V> values():获取集合中所有值的集合
      E:长度功能
              int size():返回集合中的键值对的对数

    注意:HashMap的子类:linkedHashMap   接口的哈希表和链接列表实现,具有可预知的迭代顺序。(双向链表保证有序,哈希表保证唯一)

    ----------------------------------------------------------------------------------------------------------

    对于上面的方法,看API就可以了,但是entrySet()这个方法,还是给一个例子理解一下:

    /*
     * Map集合的遍历。
     * Map -- 夫妻对
     *
     * 思路:
     *         A:获取所有结婚证的集合
     *         B:遍历结婚证的集合,得到每一个结婚证
     *         C:根据结婚证获取丈夫和妻子
     *
     * 转换:
     *         A:获取所有键值对对象的集合
     *         B:遍历键值对对象的集合,得到每一个键值对对象
     *         C:根据键值对对象获取键和值
     *
     * 这里面最麻烦的就是键值对对象如何表示呢?
     * 看看我们开始的一个方法:
     *         Set<Map.Entry<K,V>> entrySet():返回的是键值对对象(即API所说的映射项)的集合
     */
    public class MapDemo4 {
        public static void main(String[] args) {
            // 创建集合对象
            Map<String, String> map = new HashMap<String, String>();

            // 创建元素并添加到集合
            map.put("杨过", "小龙女");
            map.put("郭靖", "黄蓉");
            map.put("杨康", "穆念慈");
            map.put("陈玄风", "梅超风");

            // 获取所有键值对对象的集合
            Set<Map.Entry<String, String>> set = map.entrySet();
            // 遍历键值对对象的集合,得到每一个键值对对象
            for (Map.Entry<String, String> me : set) {
                // 根据键值对对象获取键和值
                String key = me.getKey();
                String value = me.getValue();
                System.out.println(key + "---" + value);
            }
        }
    }

    输出结果就是不按顺序的全部map映射项内容。

    -----------------------------------------------------------------------------------------------------------
        (4)Map集合的遍历
            A:键找值
                a:获取所有键的集合
                b:遍历键的集合,得到每一个键
                c:根据键到集合中去找值
            
            B:键值对对象找键和值
                a:获取所有的键值对对象的集合
                b:遍历键值对对象的集合,获取每一个键值对对象
                c:根据键值对对象去获取键和值
                
            代码体现:
                Map<String,String> hm = new HashMap<String,String>();
                
                hm.put("it002","hello");
                hm.put("it003","world");
                hm.put("it001","java");
                
                //方式1 键找值
                Set<String> set = hm.keySet();
                for(String key : set) {   //除了用增强For,还可以用迭代器,但是普通for就不行,因为无序没有索引
                    String value = hm.get(key);
                    System.out.println(key+"---"+value);
                }
                

          //与上一题无关,只是说明用迭代器也是可以遍历,因为增强for就是迭代器的变种,编译时候还是会把增强for变为迭代器,反编译就能看到

        Set<Map.Entry<Student, String>> me = map.entrySet();
        Iterator<Map.Entry<Student, String>> itt = me.iterator();
        while(itt.hasNext()){
        Map.Entry<Student, String> mee = itt.next();
          System.out.println("Key:"+mee.getKey()+"---- Value:"+mee.getValue());
        }

      
                //方式2 键值对对象找键和值
                Set<Map.Entry<String,String>> set2 = hm.entrySet();
                for(Map.Entry<String,String> me : set2) {
                    String key = me.getKey();
                    String value = me.getValue();
                    System.out.println(key+"---"+value);
                }

        
        (5)HashMap集合的练习
            A:HashMap<String,String>
            B:HashMap<Integer,String>
            C:HashMap<String,Student>
            D:HashMap<Student,String>//覆盖或重写具体类(Student)的equal方法与hashCode()方法保证map的唯一性和哈希表的散列特性
        (6)TreeMap集合的练习        
            A:TreeMap<String,String>
            B:TreeMap<Student,String>  //记住自然排序(具体类实现Comparable接口),或者比较器排序(构造方法创建匿名内部接口实现类或者创建继承Comparator接口的具体实现类),借此保证红黑二叉树(自平衡二叉树)的唯一性
        (7)案例
            A:统计一个字符串中每个字符出现的次数
            B:集合的嵌套遍历
                a:HashMap嵌套HashMap
                b:HashMap嵌套ArrayList
                c:ArrayList嵌套HashMap
                d:多层嵌套
                
    2:Collections(理解)    
        (1)是针对集合进行操作的工具类


        (2)面试题:Collection和Collections的区别
            A:Collection 是单列集合的顶层接口,有两个子接口List和Set
            B:Collections 是针对集合进行操作的工具类,可以对集合进行排序和查找等
        

     (3)常见的几个小方法:通过普通List<Integer>来进行测试
          A.   public static <T> void sort(List<T> list):排序 默认情况下是自然顺序,记住实现自然排序接口。
                public static <T> void sort(List<T> list,Comparator<? super T> c) //创建比较器为具体类规划比较路线
      B.   public static <T> int binarySearch(List<?> list,T key):二分查找
      C.   public static <T> T max(Collection<?> coll):最大值
      D.   public static void reverse(List<?> list):反转
      E.   public static void shuffle(List<?> list):随机置换


        (4)案例
            A:ArrayList集合存储自定义对象的排序

    具体类:
    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 int compareTo(Student s) {
            int num = this.age - s.age;
            int num2 = num == 0 ? this.name.compareTo(s.name) : num;
            return num2;
        }
    }

    测试类:
    /*
     * Collections可以针对ArrayList存储基本包装类的元素排序,存储自定义对象可不可以排序呢?
     */
    public class CollectionsDemo {
        public static void main(String[] args) {
            // 创建集合对象
            List<Student> list = new ArrayList<Student>();

            // 创建学生对象
            Student s1 = new Student("林青霞", 27);
            Student s2 = new Student("风清扬", 30);
            Student s3 = new Student("刘晓曲", 28);
            Student s4 = new Student("武鑫", 29);
            Student s5 = new Student("林青霞", 27);

            // 添加元素对象
            list.add(s1);
            list.add(s2);
            list.add(s3);
            list.add(s4);
            list.add(s5);

            // 排序
            // 自然排序
            // Collections.sort(list);
            // 比较器排序
            // 如果同时有自然排序和比较器排序,以比较器排序为主
            Collections.sort(list, new Comparator<Student>() {
                @Override
                public int compare(Student s1, Student s2) {
                    int num = s2.getAge() - s1.getAge();
                    int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
                            : num;
                    return num2;
                }
            });

            // 遍历集合
            for (Student s : list) {
                System.out.println(s.getName() + "---" + s.getAge());
            }
        }
    }


    ---------------------------------------------------------------------------------------------------------------------------------------------
            B:模拟斗地主洗牌和发牌 (不用排序)

     /*
     * 模拟斗地主洗牌和发牌
     *
     * 分析:
     *         A:创建一个牌盒
     *         B:装牌
     *         C:洗牌
     *         D:发牌
     *         E:看牌
     */
    public class PokerDemo {
        public static void main(String[] args) {
            // 创建一个牌盒
            ArrayList<String> array = new ArrayList<String>();

            // 装牌
            // 黑桃A,黑桃2,黑桃3,...黑桃K
            // 红桃A,...
            // 梅花A,...
            // 方块A,...
            // 定义一个花色数组
            String[] colors = { "♠", "♥", "♣", "♦" };
            // 定义一个点数数组
            String[] numbers = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                    "J", "Q", "K" };
            // 装牌
            for (String color : colors) {
                for (String number : numbers) {
                    array.add(color.concat(number));
                }
            }
            array.add("小王 ");
            array.add("大王 ");

            // 洗牌
            Collections.shuffle(array);

            // System.out.println("array:" + array);

            // 发牌
            ArrayList<String> fengQingYang = new ArrayList<String>();
            ArrayList<String> linQingXia = new ArrayList<String>();
            ArrayList<String> liuYi = new ArrayList<String>();
            ArrayList<String> diPai = new ArrayList<String>();

            for (int x = 0; x < array.size(); x++) {
                if (x >= array.size() - 3) {
                    diPai.add(array.get(x));
                } else if (x % 3 == 0) {
                    fengQingYang.add(array.get(x));
                } else if (x % 3 == 1) {
                    linQingXia.add(array.get(x));
                } else if (x % 3 == 2) {
                    liuYi.add(array.get(x));
                }
            }

            // 看牌
            lookPoker("风清扬", fengQingYang);
            lookPoker("林青霞", linQingXia);
            lookPoker("刘意", liuYi);

            lookPoker("底牌", diPai);
        }

        public static void lookPoker(String name, ArrayList<String> array) {
            System.out.print(name + "的牌是:");
            for (String s : array) {
                System.out.print(s + " ");
            }
            System.out.println();
        }
    }

    ---------------------------------------------------------------------------------------------------------------------------------------------
    C:模拟斗地主洗牌和发牌并对牌进行排序


    /*
     * 思路:
     *         A:创建一个HashMap集合
     *         B:创建一个ArrayList集合
     *         C:创建花色数组和点数数组
     *         D:从0开始往HashMap里面存储编号,并存储对应的牌
     *        同时往ArrayList里面存储编号即可。
     *      E:洗牌(洗的是编号)
     *      F:发牌(发的也是编号,为了保证编号是排序的,就创建TreeSet集合接收)
     *      G:看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
     */
    public class PokerDemo {
        public static void main(String[] args) {
            // 创建一个HashMap集合
            HashMap<Integer, String> hm = new HashMap<Integer, String>();

            // 创建一个ArrayList集合
            ArrayList<Integer> array = new ArrayList<Integer>();

            // 创建花色数组和点数数组
            // 定义一个花色数组
            String[] colors = { "♠", "♥", "♣", "♦" };
            // 定义一个点数数组
            String[] numbers = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q",
                    "K", "A", "2", };

            // 从0开始往HashMap里面存储编号,并存储对应的牌,同时往ArrayList里面存储编号即可。
            int index = 0;

            for (String number : numbers) {
                for (String color : colors) {
                    String poker = color.concat(number);
                    hm.put(index, poker);
                    array.add(index);
                    index++;
                }
            }
            hm.put(index, "小王");
            array.add(index);
            index++;
            hm.put(index, "大王");
            array.add(index);

            // 洗牌(洗的是编号)
            Collections.shuffle(array);

            // 发牌(发的也是编号,为了保证编号是排序的,就创建TreeSet集合接收)
            TreeSet<Integer> fengQingYang = new TreeSet<Integer>();
            TreeSet<Integer> linQingXia = new TreeSet<Integer>();
            TreeSet<Integer> liuYi = new TreeSet<Integer>();
            TreeSet<Integer> diPai = new TreeSet<Integer>();

            for (int x = 0; x < array.size(); x++) {
                if (x >= array.size() - 3) {
                    diPai.add(array.get(x));
                } else if (x % 3 == 0) {
                    fengQingYang.add(array.get(x));
                } else if (x % 3 == 1) {
                    linQingXia.add(array.get(x));
                } else if (x % 3 == 2) {
                    liuYi.add(array.get(x));
                }
            }

            // 看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
            lookPoker("风清扬", fengQingYang, hm);
            lookPoker("林青霞", linQingXia, hm);
            lookPoker("刘意", liuYi, hm);
            lookPoker("底牌", diPai, hm);
        }

        // 写看牌的功能
        public static void lookPoker(String name, TreeSet<Integer> ts,
                HashMap<Integer, String> hm) {
            System.out.print(name + "的牌是:");
            for (Integer key : ts) {
                String value = hm.get(key);
                System.out.print(value + " ");
            }
            System.out.println();
        }
    }


    ---------------------------------------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    中间件格式
    python3 bytes与str数据类型相互转换
    python 连接mongodb 使用
    md5 简单加密
    django 使用https协议运行runserver
    工厂模式
    C++字符串
    C++字符
    C++数学函数
    MATLAB函数总结——数值运算和符号运算
  • 原文地址:https://www.cnblogs.com/canceler/p/4622432.html
Copyright © 2011-2022 走看看