首页 > 编程语言 >24-08-08 JavaSE Map集合

24-08-08 JavaSE Map集合

时间:2024-08-13 15:25:30浏览次数:10  
标签:24 Map map 08 System println null out

24-08-08 javaSE Map集合

Map接口的特点

image-20240809000434507

  1. Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value(双列元素)

  2. Map 中的 key 和 value 可以是任何引用类型的数据,会封装到HashMap$Node 对象中

    3.  Map 中的 key 不允许重复,原因和HashSet 一样,前面分析过源码.
    
  3. Map 中的 value 可以重复

  4. Map 的key 可以为 null, value 也可以为null ,注意 key 为null,
    只能有一个,value 为null ,可以多个

  5. 常用String类作为Map的 key

  6. key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value

@SuppressWarnings({"all"})
public class Map_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("no1", "韩顺平");//k-v
        map.put("no2", "张无忌");//k-v
        map.put("no1", "张三丰");//当有相同的k , 就等价于替换.
        map.put("no3", "张三丰");//k-v
        map.put(null, null); //k-v
        map.put(null, "abc"); //等价替换
        map.put("no4", null); //k-v
        map.put("no5", null); //k-v
        map.put(1, "赵敏");//k-v
        map.put(new Object(), "金毛狮王");//k-v
        // 通过get 方法,传入 key ,会返回对应的value
        System.out.println(map.get("no2"));//张无忌
        System.out.println("map=" + map);
    }
}

张无忌
map={no2=张无忌, null=abc, no1=张三丰, 1=赵敏, no4=null, java.lang.Object@1eb44e46=金毛狮王, no3=张三丰, no5=null}

Map接口源码讲解

@SuppressWarnings({"all"})
public class MapSource_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("no1", "韩顺平");//k-v
        map.put("no2", "张无忌");//k-v
        map.put(new Car(), new Person());//k-v
        Set set = map.entrySet();
        System.out.println(set.getClass());// HashMap$EntrySet
        for (Object obj : set) {
        Map.Entry entry = (Map.Entry) obj;
        System.out.println(entry.getKey() + "-" + entry.getValue() );
        }
        Set set1 = map.keySet();
        System.out.println(set1.getClass());
        Collection values = map.values();
        System.out.println(values.getClass());
    }
}

class Car {

}

class Person{

}
  1. k-v 最后是 HashMap$Node node = newNode(hash, key, value, null),Node是内部类

image-20240809002501915

image-20240809002526470

  1. k-v 为了方便程序员的遍历,还会 创建 EntrySet 集合 ,该集合存放的元素的类型 Entry, 而一个Entry对象就有k,v 。相当于EntrySet<Entry<K,V>>

  2. image-20240809003343596

    image-20240809002806869

    Set set = map.entrySet(); System.out.println(set.getClass());// HashMap$EntrySet
    
  3. entrySet 中, 定义的类型是 Map.Entry ,但是实际上存放的还是 HashMap$Node,因为node类型实现了Entry;

image-20240809003904717

  1. 当把 HashMap$Node 对象 存放到 entrySet 就方便我们的遍历, 因为 Map.Entry类 提供了重要方法K getKey(); V getValue();
for (Object obj : set) {       System.out.println(obj.getClass()); 				//HashMap$Node
    //为了从 HashMap$Node 取出k-v
    //1. 先做一个向下转型
    Map.Entry entry = (Map.Entry) obj;
    System.out.println(entry.getKey() + "-" + entry.getValue() );
}

总结:首先HashMap里面的Note类型节点的引用会先转为Entry类型(因为node实现了entry)然后这个entry类型结点会放到EntrySet里面,EntrySet里面的key和Value值分别以set和collection形式存储,当然存储的也是引用。

我们可以更加直观的看到node->Entry的指向关系。

image-20240809005405292

我们可以更直观的看到EntrySet里面的key和Value值分别以set和collection形式存储(为了能够单独拿出来)

Set set1 = map.keySet();
System.out.println(set1.getClass());
Collection values = map.values();
System.out.println(values.getClass());

image-20240809005749840

KeySet继承AbstractSet,Values是继承AbstractSet的

image-20240809005957581

image-20240809010013855

我们对下面这张图片有了更清晰的认识image-20240809002806869

Map的常用方法

Map map = new HashMap();
        map.put("邓超", new Book("", 100));//OK
        map.put("邓超", "孙俪");//替换-> 一会分析源码
        map.put("王宝强", "马蓉");//OK
        map.put("宋喆", "马蓉");//OK
        map.put("刘令博", null);//OK
        map.put(null, "刘亦菲");//OK
        map.put("鹿晗", "关晓彤");//OK
        map.put("hsp", "hsp的老婆");
        System.out.println("map=" + map);
//        remove:根据键删除映射关系
        map.remove(null);
        System.out.println("map=" + map);
//        get:根据键获取值
        Object val = map.get("鹿晗");
        System.out.println("val=" + val);
//        size:获取元素个数
        System.out.println("k-v=" + map.size());
//        isEmpty:判断个数是否为0
        System.out.println(map.isEmpty());//F
//        clear:清除k-v
        //map.clear();
        System.out.println("map=" + map);
//        containsKey:查找键是否存在
        System.out.println("结果=" + map.containsKey("hsp"));//T


    }
}

class Book {
    private String name;
    private int num;

    public Book(String name, int num) {
        this.name = name;
        this.num = num;
    }
}

输出如下:

image-20240809010341843

Map接口三种途径的遍历方法

@SuppressWarnings({"all"})
public class MapFor {
    public static void main(String[] args) {

        Map map = new HashMap();
        map.put("邓超", "孙俪");
        map.put("王宝强", "马蓉");
        map.put("宋喆", "马蓉");
        map.put("刘令博", null);
        map.put(null, "刘亦菲");
        map.put("鹿晗", "关晓彤");

        //第一组: 先取出 所有的Key , 通过Key 取出对应的Value
        Set keyset = map.keySet();
        //(1) 增强for
        System.out.println("-----第一种方式-------");
        for (Object key : keyset) {
            System.out.println(key + "-" + map.get(key));
        }
        //(2) 迭代器
        System.out.println("----第二种方式--------");
        Iterator iterator = keyset.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key + "-" + map.get(key));
        }


        //第二组: 把所有的values取出
        Collection values = map.values();
        //这里可以使用所有的Collections使用的遍历方法
        //(1) 增强for
        System.out.println("---取出所有的value 增强for----");
        for (Object value : values) {
            System.out.println(value);
        }
        //(2) 迭代器
        System.out.println("---取出所有的value 迭代器----");
        Iterator iterator2 = values.iterator();
        while (iterator2.hasNext()) {
            Object value =  iterator2.next();
            System.out.println(value);

        }

        //第三组: 通过EntrySet 来获取 k-v
        Set entrySet = map.entrySet();// EntrySet<Map.Entry<K,V>>
        //(1) 增强for
        System.out.println("----使用EntrySet 的 for增强(第3种)----");
        for (Object entry : entrySet) {
            //向下转型 将entry 转成 Map.Entry
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "-" + m.getValue());
        }
        //(2) 迭代器
        System.out.println("----使用EntrySet 的 迭代器(第4种)----");
        Iterator iterator3 = entrySet.iterator();
        while (iterator3.hasNext()) {
            Object entry =  iterator3.next();
            //System.out.println(next.getClass());//HashMap$Node -实现-> Map.Entry (getKey,getValue)
            //向下转型 Map.Entry
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "-" + m.getValue());
        }


    }
}

注:所有继承Collection接口的类都可以使用iterator迭代器。

输出结果如下:

-----第一种方式-------
邓超-孙俪
宋喆-马蓉
刘令博-null
null-刘亦菲
王宝强-马蓉
鹿晗-关晓彤
----第二种方式--------
邓超-孙俪
宋喆-马蓉
刘令博-null
null-刘亦菲
王宝强-马蓉
鹿晗-关晓彤
—取出所有的value 增强for----
孙俪
马蓉
null
刘亦菲
马蓉
关晓彤
—取出所有的value 迭代器----
孙俪
马蓉
null
刘亦菲
马蓉
关晓彤
----使用EntrySet 的 for增强(第3种)----
邓超-孙俪
宋喆-马蓉
刘令博-null
null-刘亦菲
王宝强-马蓉
鹿晗-关晓彤
----使用EntrySet 的 迭代器(第4种)----
邓超-孙俪
宋喆-马蓉
刘令博-null
null-刘亦菲
王宝强-马蓉
鹿晗-关晓彤

进程已结束,退出代码为 0

Map接口练习题

image-20240809015703848

@SuppressWarnings({"all"})
public class MapExercise {
    public static void main(String[] args) {
        Employee xiaoming = new Employee("小明", 50000, "123456");
        Employee xiaohong = new Employee("小红", 10000, "123457");
        Employee xiaofang = new Employee("小芳", 3000, "123458");
        Map hashMap = new HashMap();
        hashMap.put(xiaoming.getId(), xiaoming);
        hashMap.put(xiaohong.getId(), xiaohong);
        hashMap.put(xiaofang.getId(), xiaofang);
        Set set = hashMap.keySet();
        for (Object object : set) {
            Employee employee = (Employee) hashMap.get(object);
            if (employee.getSalary() > 18000)
                System.out.println(object + "-" + hashMap.get(object));
        }

//        Iterator iterator = set.iterator();
//        while (iterator.hasNext()) {
//            Object next = iterator.next();
//            System.out.println(next + "-" + hashMap.get(next));
//        }

        Set set1 = hashMap.entrySet();
//        for (Object object : set1) {
//            Map.Entry object1 = (Map.Entry) object;
//            System.out.println(object1.getKey() + "-" + object1.getValue());
//        }

        Iterator iterator1 = set1.iterator();
        while (iterator1.hasNext()) {
            Object next = iterator1.next();
            Map.Entry next1 = (Map.Entry) next;
            Employee value = (Employee) next1.getValue();
            if (value.getSalary() > 18000)
                System.out.println(next1.getKey() + "-" + next1.getValue());
        }


    }
}

class Employee {
    private String name;
    private double salary;
    private String id;

    public Employee(String name, double salary, String id) {
        this.name = name;
        this.salary = salary;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", id='" + id + '\'' +
                '}';
    }
}

HashMap小结

  1. Map接口的常用实现类:HashMap、Hashtable和Properties。

  2. HashMap是Map接口使用频率最高的实现类。

  3. HashMap 是以key-val对的方式来存储数据(HashMap$Node类型)

  4. key 不能重复,但是值可以重复,允许使用null键和null值。如果添加相同的key,则会覆盖原来的key-val,等同于修改.(key不会替换,val会替换)

    替换源码部分:

    image-20240809021331607

  5. 与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的.(jdk8的hashMap底层 数组+链表+红黑树)

  6. HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronized

hMap小结

  1. Map接口的常用实现类:HashMap、Hashtable和Properties。

  2. HashMap是Map接口使用频率最高的实现类。

  3. HashMap 是以key-val对的方式来存储数据(HashMap$Node类型)

  4. key 不能重复,但是值可以重复,允许使用null键和null值。如果添加相同的key,则会覆盖原来的key-val,等同于修改.(key不会替换,val会替换)

    替换源码部分:

    [外链图片转存中…(img-bRXakQ9z-1723519058095)]

  5. 与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的.(jdk8的hashMap底层 数组+链表+红黑树)

  6. HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronized

持续更新。。。

标签:24,Map,map,08,System,println,null,out
From: https://blog.csdn.net/2301_79291071/article/details/141159337

相关文章

  • 2024年这3款翻译工具,真的能帮你摆脱‘词不达意’的尴尬
    在现在这个全球化越来越普遍的时代,会翻译东西对我们来说越来越重要,无论是学习、工作还是日常生活中。不过,对很多刚开始学翻译的人来说,这事儿可能看起来挺难的。别急,到了2024年,有几款好用的翻译工具,就算是翻译新手也能很快上手。今天,咱们就来说说这些工具如何帮我们更好地理解和......
  • 盘点2024年让互联网人打Call的录屏大师,你种草了吗?
    嘿,朋友们,你们有没有为录个教程、直播回放或者游戏精彩瞬间而烦恼过?市面上录屏软件一大堆,但真正能让你录得开心、录出新高度的软件可不好找!今天我这个录屏大师就来给你们介绍2024年三款超棒的录屏神器,让你的录屏过程变得既有趣又轻松!一:Foxit专业录屏武器即时通道___ https:/......
  • 24.python模块
    python中的模块(一)模块的介绍1、python中模块:模块也是一个python文件,也叫.py文件2、一个模块中包含:类、函数、变量、方法等3、模块的结构:4、一个模块能够有逻辑的组织python的代码段二、模块的导入1、import模块名importtimeprint(1)time.sleep(5)print(2)2、fro......
  • 2024最新最全【AIGC】学习零基础入门到精通,看完这一篇就够了!
    AIGC(AI-GeneratedContent)即人工智能生成内容,是指利用人工智能技术来创造各种形式的内容,包括文字、图像、视频、音频和游戏等。与专业生成内容(PGC)和用户生成内容(UGC)相对应,AIGC代表着内容生产方式的演进,其生产速度以指数级增长。为什么要学习AIGC?根据猎聘大数据研究院发布......
  • 基于SpringBoot和Vue的汽车租赁系统设计与实现(全网唯一,24年最新定做)
    文章目录前言详细视频演示论文参考具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我自己的网站([小蔡coding](https://xiaocaicoding.cn/))代码参考数据库参考源码获取前言......
  • 东舟技术诚邀相聚2024汽车测试及质量监控博览会
      引领汽车测试行业的年度盛会即将拉开帷幕!2024汽车测试及质量监控博览会将于2024年8月28日至30日在上海世博展览馆1号馆盛大举行。 它已牢固确立为不可或缺的测试和验证技术展会,涵盖从样车到生产的全过程,展示大量用于测试、开发和验证阶段的新设备,以实现更好的耐久性、......
  • macOS Sequoia 15 beta 6 (24A5320a) ISO、IPSW、PKG 下载
    macOSSequoia15beta6(24A5320a)ISO、IPSW、PKG下载iPhone镜像、Safari浏览器重大更新、备受瞩目的游戏和AppleIntelligence等众多全新功能令Mac使用体验再升级请访问原文链接:https://sysin.org/blog/macOS-Sequoia/,查看最新版。原创作品,转载请保留出处。作者主页......
  • macOS Sequoia 15.1 beta 2 (24B5024e) ISO、IPSW、PKG 下载
    macOSSequoia15.1beta2(24B5024e)ISO、IPSW、PKG下载iPhone镜像、Safari浏览器重大更新、备受瞩目的游戏和AppleIntelligence等众多全新功能令Mac使用体验再升级请访问原文链接:https://sysin.org/blog/macOS-Sequoia/,查看最新版。原创作品,转载请保留出处。作者主......
  • macOS Sequoia 15 beta 6 (24A5320a) Boot ISO 原版可引导镜像下载
    macOSSequoia15beta6(24A5320a)BootISO原版可引导镜像下载iPhone镜像、Safari浏览器重大更新、备受瞩目的游戏和AppleIntelligence等众多全新功能令Mac使用体验再升级请访问原文链接:https://sysin.org/blog/macOS-Sequoia-boot-iso/,查看最新版。原创作品,转载请保......
  • 【2024-08-11】连岳摘抄
    23:59幸福其实来自对人生的投入,而不是与之脱离。                                                 ——乔纳森·海特你是典型的体制从业者,有幸运的一面,也有不幸的一......