• 深入了解Map


    联系

    Java中的Map类似于OC的Dictionary,都是一个个键值对组成,一键对应一值。我在之前的文章中讲解过Set,其实在JAVA底层Set依赖的也是Map,那我们都知道,Set是单列的(只有值),而Map是双列的,怎么会是Set依赖Map呢?其实做法也很简单,Set将Key隐藏,只允许访问value就实现了Set的单列效果。

    功能

    *a:添加功能
        * V put(K key,V value):添加元素。
            * 如果键是第一次存储,就直接存储元素,返回null
            * 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
    

    Map的遍历

    方式一
      //通过获取所有的键来遍历值
            Map<String, Integer> map = new HashMap<>();
            map.put("张三", 23);
            map.put("李四", 24);
            map.put("王五", 25);
            map.put("赵六", 26);
    
            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);
            }
    

    使用迭代器遍历,但是有些复杂,可以改进

    方式二 (方式一改进,较简单)

    这种遍历方式类似于OC中for···in语法

            //使用增强for循环遍历
            for(String key : map.keySet()) {            //map.keySet()是所有键的集合
                System.out.println(key + "=" + map.get(key));
            }
    
    方式三 键值对对象遍历
            //Map.Entry说明Entry是Map的内部接口,将键和值封装成了Entry对象,并存储在Set集合中
            Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
            //获取每一个对象
            Iterator<Map.Entry<String, Integer>> it = entrySet.iterator();
            while(it.hasNext()) {
                //获取每一个Entry对象
                Map.Entry<String, Integer> en = it.next();    //父类引用指向子类对象
                //Entry<String, Integer> en = it.next();    //直接获取的是子类对象
                String key = en.getKey();                    //根据键值对对象获取键
                Integer value = en.getValue();                //根据键值对对象获取值
                System.out.println(key + "=" + value);
            }
    
    方式四 (方式三改进)
            for(Entry<String, Integer> en : map.entrySet()) {
                System.out.println(en.getKey() + "=" + en.getValue());
            }
    

    LinkedHashMap

    LinkedHashMap可以保证怎么存就怎么取

        public static void main(String[] args) {
            LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>();
            lhm.put("张三", 23);
            lhm.put("李四", 24);
            lhm.put("赵六", 26);
            lhm.put("王五", 25);
    
            System.out.println(lhm);
        }
    

    TreeMap

    利用TreeMap可实现对键的自定义排序,同时键应为自定义类对象,同时需要在自定义类中重写compareTo方法,和hashSet里面的排序大致相同。

    //按照Student的姓名排序,姓名相同按照年龄排序
    public static void main(String[] args) {
            //demo1();
            TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() {
    
                @Override
                public int compare(Student s1, Student s2) {
                    int num = s1.getName().compareTo(s2.getName());        //按照姓名比较
                    return num == 0 ? s1.getAge() - s2.getAge() : num;
                }
            });
            tm.put(new Student("张三", 23), "北京");
            tm.put(new Student("李四", 13), "上海");
            tm.put(new Student("赵六", 43), "深圳");
            tm.put(new Student("王五", 33), "广州");
    
            System.out.println(tm);
        }
    

    利用HashMap统计字符串中每个字符出现的次数

    核心思想就是利用HashMap的containsKey()来判断是否重复。

    /**
         * * A:案例演示
         * 需求:统计字符串中每个字符出现的次数
         * 
         * 分析:
         * 1,定义一个需要被统计字符的字符串
         * 2,将字符串转换为字符数组
         * 3,定义双列集合,存储字符串中字符以及字符出现的次数
         * 4,遍历字符数组获取每一个字符,并将字符存储在双列集合中
         * 5,存储过程中要做判断,如果集合中不包含这个键,就将该字符当作键,值为1存储,如果集合中包含这个键,就将值加1存储
         * 6,打印双列集合获取字符出现的次数
         */
        public static void main(String[] args) {
            //1,定义一个需要被统计字符的字符串
            String s = "aaaabbbbbccccccccccccc";
            //2,将字符串转换为字符数组
            char[] arr = s.toCharArray();
            //3,定义双列集合,存储字符串中字符以及字符出现的次数
            HashMap<Character, Integer> hm = new HashMap<>();
            //4,遍历字符数组获取每一个字符,并将字符存储在双列集合中
            for(char c: arr) {
                //5,存储过程中要做判断,如果集合中不包含这个键,就将该字符当作键,值为1存储,如果集合中包含这个键,就将值加1存储
                /*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);
            }
            //6,打印双列集合获取字符出现的次数
    
            for (Character key : hm.keySet()) {                //hm.keySet()代表所有键的集合
                System.out.println(key + "=" + hm.get(key));//hm.get(key)根据键获取值
            }
        }
    
    案例演示:

    集合嵌套之HashMap嵌套HashMap

    需求:

    一个年级有很多班,
    一班定义为一个双列结合,键是学生对象,值是学生的归属地,
    二班定义为一个双列结合,键是学生对象,值是学生的归属地。
    无论一班二班都是班级对象,所以为了编译统一管理,把这些班级对象添加到某个年级中。

            //定义一班
            HashMap<Student, String> hm88 = new HashMap<>();
            hm88.put(new Student("张三", 23), "北京");
            hm88.put(new Student("李四", 24), "北京");
            hm88.put(new Student("王五", 25), "上海");
            hm88.put(new Student("赵六", 26), "广州");
    
            //定义二班
            HashMap<Student, String> hm99 = new HashMap<>();
            hm99.put(new Student("唐僧", 1023), "北京");
            hm99.put(new Student("孙悟空",1024), "北京");
            hm99.put(new Student("猪八戒",1025), "上海");
            hm99.put(new Student("沙和尚",1026), "广州");
    
            //定义年级
            HashMap<HashMap<Student, String>, String> hm = new HashMap<>();
            hm.put(hm88, "一班");
            hm.put(hm99, "二班");
    
            //遍历双列集合
            for(HashMap<Student, String> h : hm.keySet()) {        //hm.keySet()代表的是双列集合中键的集合
                String value = hm.get(h);                        //get(h)根据键对象获取值对象
                //遍历键的双列集合对象
                for(Student key : h.keySet()) {                    //h.keySet()获取集合总所有的学生键对象
                    String value2 = h.get(key);
    
                    System.out.println(key + "=" + value2 + "=" + value);
                }
            }
    

    hashMap和hashTable的区别

    共同点:

    底层都是哈希算法,都是双列集合

    区别:
    1. HashMap是线程不安全的,效率高,JDK1.2版本,Hashtable是线程安全的,效率低,JDK1.0版本的
    2. HashMap可以存储null键和null值,Hashtable不可以存储null键和null值
  • 相关阅读:
    okhttp之源码学习1
    Retrofit2之源码解析2
    Retrofit2之源码解析1
    retrofit之笔记内容
    retrofit之基本笔记
    retrofit之基本内容
    rxjava-源码分析
    rxjava-基本内容解析
    rxjava_几类转换
    java几种常见的编码
  • 原文地址:https://www.cnblogs.com/yzssoft/p/7256298.html
Copyright © 2020-2023  润新知