• java编程基础总结——24.Map接口及其实现子类


    一、Map接口:

       map接口,是一种键值对的式的结构,开发中,经常使用这种结构

        key:键,是唯一的,不能重复,若重复,则会覆盖原有key中的值(哈希表中是唯一的,不能                 重复),所以用哈希表去维护,map之所以用hashmap的原因是要保证key的唯一性

        value : 值    可以重复

        注意:Map接口没有继承Collection

    1. 常见方法:

    map是接口,不能实例化,所以得用它的子类

    在java中,Map的key可以是任意类型(泛型)

      

    1)添加

      V put(K key, V value);

      当key重复时,不会创建多个键值对,只会进行覆盖

      在HashMap中,可以使用null作为key

       2)获取

       V get(Object key); 

       如果获取的key不存在,则返回空 

    1. import java.util.Map;
    2. @Test
    3. void testMap01() {
    4. Map mps = new HashMap<>();
    5. mps.put("name", 123);
    6. mps.put("age", 23);
    7. mps.put("gender", 56);
    8. // 当key重复时,不会创建多个键值对,只会进行覆盖
    9. mps.put("gender", 100);
    10. System.out.println(mps);
    11. System.err.println(mps.size());
    12. System.err.println(mps.get("name"));
    13. // 如果获取的key不存在,则返回空
    14. System.err.println(mps.get("nickname"));
    15. // 在HashMap中,以null作为key,可以不?
    16. // 在HashMap中,可以使用null作为key
    17. mps.put(null, 123);
    18. System.out.println(mps);
    19. System.out.println(mps.get(null));
    20. }

     3)getOrDefault、containsKey、remove、replace

    1. @Test
    2. void testMap02() {
    3. Map mps = new HashMap<>();
    4. mps.put("name", "小豪");
    5. mps.put("age", "13");
    6. mps.put("gender", "男");
    7. // 获取时,如果存在,则返回,如果不存在,则给定一个默认值
    8. System.out.println(mps.getOrDefault("name2", "佚名"));
    9. //是否包含某个键
    10. System.out.println(mps.containsKey("name"));
    11. System.out.println(mps.containsKey("nickname"));
    12. // 根据key 移除整个键值对
    13. System.out.println(mps.remove("name"));
    14. System.out.println(mps);
    15. // 根据key和value,移除整个键值对,键和值都匹配才会移除
    16. System.out.println(mps.remove("age", "20"));
    17. System.out.println(mps);
    18. System.out.println(mps.remove("age", "13"));
    19. System.out.println(mps);
    20. // 注意,仅仅是替换key对应的值,如果没有,不会添加
    21. mps.replace("gender", "male");
    22. System.out.println(mps);
    23. mps.replace("gender1", "male");
    24. System.out.println(mps);
    25. }

     

    2. 遍历map结构

    1. @Test
    2. void testMap03() {
    3. Map mps = new HashMap<>();
    4. mps.put("name", "小豪");
    5. mps.put("age", 13);
    6. mps.put("gender", "男");
    7. mps.put("address", "汉中");
    8. }

    1).  keySet()

    // 注意:这个方法错误,每当调一次next()就会向前走一次
    //        Set keySet = mps.keySet();
    //        Iterator keys = keySet.iterator();
    //        while (keys.hasNext()) {
    //            System.out.println(keys.next() +"---->"+ mps.get(keys.next()));
    //        }

    1. //用这种方法进行迭代(迭代器)
    2. // keySet(),将map的key 做成set,再迭代数据
    3. Set keySet = mps.keySet();//key是字符串,返回的set的类型是字符串类型
    4. Iterator keys = keySet.iterator();
    5. while (keys.hasNext()) {
    6. String key = keys.next();
    7. System.out.println(key +"---->"+ mps.get(key));
    8. }
    9. //使用for循环加强简化迭代器
    10. for (String key : mps.keySet()) {
    11. System.out.println(key +"---->"+ mps.get(key));
    12. }

     

    2).entrySet()

    1. //Entry返回的是map中的每一个键值对,返回的是set类型
    2. Set> entrySet = mps.entrySet();
    3. //迭代器
    4. Iterator> iterator = entrySet.iterator();
    5. while(iterator.hasNext()) {
    6. System.out.println(iterator.next());
    7. }
    8. // while(iterator.hasNext()) {
    9. // Entry set = iterator.next();
    10. // System.out.println(set);
    11. // }
    12. //for循环加强
    13. for (Entry entry : entrySet) {
    14. System.out.println(entry.getKey() +"---->"+ entry.getValue());
    15. }

    3).forEach()

    // 使用lambda表达式,简化遍历操作

    entrySet.forEach(t -> System.out.println(t.getKey() +"---->"+ t.getValue()));

    //之前提到的forEach的写法都可以用

    4).jdk8提供的新的map自身的一种遍历方式

    mps.forEach((k, v) -> System.out.println(k +"---->"+ v));

     

     

    二、Map的常见实现子类:

    HashMap      

    Hashtable

    ConcurrentHashMap

    1. 三者区别和联系:

        HashMap       非线程安全                        jdk1.2诞生
        Hashtable(同步锁)线程安全                jdk1.0诞生

                    这个规则类似于线性表中的ArrayList和Vector

                     ArrayList        非线程安全                jdk1.2诞生
                     Vector(同步锁)线程安全             jdk1.0诞生


        ConcurrentHashMap(Hashtable可以解决高并发,但随着技术的发展,用                                                                        ConcurrentHashMap)   jdk1.5诞生                                                                                                对HashMap进行改造,在HashMap中分段锁的机制

              HashMap 默认由大小为16的数组组成,ConcurrentHashMap对每个节点进行加锁操作,相            当于加了16个分段锁,使得线程安全,但是效率比Hashtable至少高16倍。jdk8之后进行优化,做了自旋锁,本质不是锁,所以效率更高。

                                         
    2. HashMap简介:

        它是一个标准的哈希表
        JDK8之前,HashMap:整体结构是一个"数组 + 链表" 结构

        JDK8之后,HashMap:整体结构是一个"数组 + 链表 + 红黑树" 结

    1)、哈希冲突:

    (1).什么是哈希冲突

              哈希冲突是指哈希函数算出来的地址被别的元素占用了。

    (2).哈希冲突的四种解决方案:

              1、再哈希法
              2、开放定址法
              3、链地址法
              4、建立公共溢出区:

  • 相关阅读:
    【链接装载与库】 Linux共享库的组织
    如何在 DigitalOcean Kubernetes 上设置 NGINX 入口控制器
    C++ explicit关键字使用方法
    云安全—NIST SP 500-292
    我用GPT4 预测了10年后中国大学排名Top10
    【python】--python环境安装及配置
    【docker】Error response from daemon Container is not running
    提升个人效率减少焦虑——GTD法则
    秒懂算法 | 数论算法实例分析之阿里巴巴的宝藏与欧拉函数例题
    Managing Supply and Demand Balance Through Machine Learning-笔记
  • 原文地址:https://blog.csdn.net/m0_58679504/article/details/126224506