Java集合类学习--Map

c++ map/unordered_map和vector混合数据结构的赋值插值操作   如下示例和注释所示: 阅读详情

概述

Map 是一个接口,它表示一种“键-值(key-value)”映射的对象(Entry),其中键是不重复的(值可以重复),且最多映射到一个值(可以理解为“映射”或者“字典”)。

Map 常用的实现类有 HashMap、TreeMap、ConcurrentHashMap、LinkedHashMap 等,它们的继承结构如下:
在这里插入图片描述
接口下的方法有:
在这里插入图片描述

源码分析

常用方法

// 将键-值对存入 Map,若 key 对应的 value 已存在,则将其替换
// 返回原先 key 对应的 value(若不存在,返回 null)
V put(K key, V value);

// 将指定 Map 中的所有元素拷贝到本 Map 中
void putAll(Map<? extends K, ? extends V> m);

// 返回本 Map 中所有 key 的 Set 视图
Set<K> keySet();

// 返回本 Map 中所有 value 的 Collection 视图
Collection<V> values();

// 返回本 Map 中所有 Entry 的 Set 视图
// 其中 Entry 是 Map 内部的一个接口,可以理解为 Map 的“元数据”
Set<Map.Entry<K, V>> entrySet();

java8新增方法:

// 获取 key 对应的 value,若 value 为 null,则返回 defaultValue
default V getOrDefault(Object key, V defaultValue) {
    V v;
    return (((v = get(key)) != null) || containsKey(key))
        ? v
        : defaultValue;
}

// 遍历 Map 中的元素
default void forEach(BiConsumer<? super K, ? super V> action) {
    Objects.requireNonNull(action);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
        action.accept(k, v);
    }
}

// 通过给定的函数计算出新的 Entry 替换所有旧的 Entry
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
    Objects.requireNonNull(function);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
        // ise thrown from function is not a cme.
        v = function.apply(k, v);
        try {
            entry.setValue(v);
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
    }
}

// 若 key 对应的 value 不存在,则把 key-value 存入 Map,否则无操作
default V putIfAbsent(K key, V value) {
    V v = get(key);
    if (v == null) {
        v = put(key, value);
    }

    return v;
}

// 若 key 对应的值等于 value,则移除 key;否则无操作
default boolean remove(Object key, Object value) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, value) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    remove(key);
    return true;
}

// 若 key 对应的值等于 oldValue,则将其替换为 newValue;否则无操作
default boolean replace(K key, V oldValue, V newValue) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, oldValue) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    put(key, newValue);
    return true;
}

// Map 中存在 key 时,将 key-value 存入,相当于:
/*
  if (map.containsKey(key)) {
      return map.put(key, value);
  } else
      return null;
  }
 */
default V replace(K key, V value) {
    V curValue;
    if (((curValue = get(key)) != null) || containsKey(key)) {
        curValue = put(key, value);
    }
    return curValue;
}

// 当 key 对应的 value 不存在时,使用给定的函数计算得出 newValue
// 并将 key-newValue 存入 Map
default V computeIfAbsent(K key,
        Function<? super K, ? extends V> mappingFunction) {
    Objects.requireNonNull(mappingFunction);
    V v;
    if ((v = get(key)) == null) {
        V newValue;
        if ((newValue = mappingFunction.apply(key)) != null) {
            put(key, newValue);
            return newValue;
        }
    }
    return v;
}

// 当 key 对应的 value 存在时,使用给定的函数计算得出 newValue,
// 当 newValue 不为 null 时将 key-newValue 存入 Map;否则移除 key
default V computeIfPresent(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue;
    if ((oldValue = get(key)) != null) {
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue != null) {
            put(key, newValue);
            return newValue;
        } else {
            remove(key);
            return null;
        }
    } else {
        return null;
    }
}

// 根据 key 和其对应的 oldValue,使用给定的函数计算出 newValue
// 若 newValue 为 null
//   若 oldValue 不为空或 key 存在,则删除 key-oldValue
//   否则无操作
// 若 newValue 不为 null,用 newValue 替换 oldValue
default V compute(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue = get(key);
    V newValue = remappingFunction.apply(key, oldValue);
    if (newValue == null) {
        // delete mapping
        if (oldValue != null || containsKey(key)) {
            // something to remove
            remove(key);
            return null;
        } else {
            // nothing to do. Leave things as they were.
            return null;
        }
    } else {
        // add or replace old mapping
        put(key, newValue);
        return newValue;
    }
}

default V merge(K key, V value,
        BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    Objects.requireNonNull(value);
    V oldValue = get(key);
    V newValue = (oldValue == null) ? value :
               remappingFunction.apply(oldValue, value);
    if(newValue == null) {
        remove(key);
    } else {
        put(key, newValue);
    }
    return newValue;
}

1.8 中的几个方法看似比较复杂,但有些方法实质上相当于对一些 if…else 语句的封装,利用 lambda 表达式可以让代码更简洁。

内部接口
Map 接口内部还定义了一个 Entry 接口(上面已经出现),它其实相当于 Map 内部存储的「元数据」,也就是 键-值(key-value) 映射。方法列表如下:在这里插入图片描述

其中前面几个方法都比较简单,这里分析下后面几个 JDK 1.8 引入的方法:

// 返回一个比较器,它以自然顺序比较 Entry 的 key
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
    return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getKey().compareTo(c2.getKey());
}

// 返回一个比较器,它以自然顺序比较 Entry 的 value
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
    return (Comparator<Map.Entry<K, V>> & Serializable)
        (c1, c2) -> c1.getValue().compareTo(c2.getValue());
}

// 返回一个比较器,它使用给定的 Comparator 比较 Entry 的 key
public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
    Objects.requireNonNull(cmp);
    return (Comparator<Map.Entry<K, V>> & Serializable)
        (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
}

// 返回一个比较器,它使用给定的 Comparator 比较 Entry 的 value
public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
    Objects.requireNonNull(cmp);
    return (Comparator<Map.Entry<K, V>> & Serializable)
        (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}

总结

Map 接口虽然没有继承自 Collection 接口,但也是JCF(Java Collections Framework) 的一部分;
Map 存储的是键-值(key-value)映射结构的对象;
Entry 接口定义在其内部,它是真正定义键-值映射的结构,相当于 Map 的「元数据」。

Debian下Rust环境极速安装指南:国内镜像+避坑配置(附清华/中科大源对比) 本文详细介绍了在Debian系统上快速安装和配置Rust开发环境的完整指南。针对国内网络环境,重点对比评测了清华大学、中国科学技术大学等主流镜像源,提供了详细的安装配置步骤、Cargo优化技巧以及常见问题排查方案,帮助开发者显著提升依赖下载和编译效率。 阅读详情

相关推荐

2 利用ITK实现多帧Dicom读取,VTK实现数据显示

vtk中也有dicom读写类,但是只能完成单帧DICOM数据读取,这对于实际应用是非常不利的。而ITK可以实现dicom多帧读取,通常情况ITK与VTK也会结合使用(ITK处理,VTK显示),所以就一起学习下吧!

buerbuhuitou的博客 1564

C++中map和vector使用

printf("key不存在");printf("key存在");printf("key存在");

nightwalker2130的博客 711

2021-8-14 EDK II编译

2021-8-14 EDK II 编译为什么要写这篇文章新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 为什么要写这篇文章 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdo

qq_45775660的博客 2946

c++ 如何在map value上增添值_如何泄漏一个协程然后修复它

很多 go 语言开发者都知道这句格言,永远不要启动一个你不知道如何停止的协程,但是泄漏一个协程还是超级的简单。让我们看一种常碰到的泄漏协程的方式,然后修复它。为了实现这个,我们先建立一个包含一个自定义 map 类型的库,这个 map 类型的 key 在经过了一段可配置的时间后过期。我们把这个库叫做 ttl ,这个库有一个 API 类似如下:// 创建一个生存周期为5分钟的map m := ttl....

weixin_39623716的博客 167

【CubeMX】STM32G474 HRTIM 死区时间与互补PWM实战解析

本文深入解析STM32G474的HRTIM高分辨率定时器在互补PWM生成与死区时间配置中的应用。通过CubeMX工具详细演示时钟配置、单路PWM基础、互补输出与死区时间设置,并结合逆变器等电力电子实战案例,帮助开发者避免直通风险,优化系统性能。

efc12345678的博客 746

STM32CubeMX的正交编码器encoder

由于最近干活遇到需要获取正交编码的功能,所以返回来研究一下STM32CubeMX的编码器功能,之前也更新过STM32的定时器功能,但是因为之前搞平衡车的正交编码器没有搞清楚原理,就直接用了脉冲输入功能草草了事,现在也算是为之前的年轻买单了,不过看到现有的Encoder说明都比较简单,所以就当是为开发者做贡献了,我研究清楚之后来一篇博客。

ASWaterbenben的博客 1万+

c++ 如何在map value上增添值_手把手一起从 0 实现 Vue3 响应式原理(上)

前言笔者最近在浏览React状态管理库的时候,发现了一些响应式的状态管理库如hodux,react-easy-state,内部有一个基于proxy实现响应式的基础仓库observer-util,它的代码实现和Vue3中的响应式原理非常相似,这篇文章就从这个仓库入手,一步一步带你剖析响应式的实现。本篇是系列第一篇,主要讲解了普通对象的响应式源码系列终结篇也已经发布,讲解Map和Set的特殊...

weixin_35726575的博客 310

保姆级教程:用高云GW2A开发板搭建RISC-V软核处理器(含DDR3内存优化配置)

本文提供了一份详细的保姆级教程,指导开发者使用高云GW2A-LV18PG256C8 FPGA开发板搭建RISC-V软核处理器系统。教程涵盖了从开发环境搭建、PicoRV32软核集成,到关键的DDR3内存控制器配置与优化,并深入讲解了时序约束与系统调试方法,帮助初学者和爱好者实现从逻辑设计到软硬件协同的深度实践。

2a4s6d8f0g的博客 565

C++—— vector用法(详解!!函数,实现)

C++ vector的用法(整理) vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器。vector 是C++ STL的一个重要成员,使用它时需要包含头文件: #include<vector>; 一、vector 的初始化:可以有五种方式,举例说明如下: (1) vector<int> a(10); //定义了10个整型元素...

优快云131137的博客 7144

STM32CubeMX | 38-使用硬件SPI驱动以太网模块(W5500)

本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SPI外设与以W5500通信,驱动以太网模块。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): W5500以太网模块 这里我使用常见的以太网模块W5500: W5500官网 http://www.w5500.cn/ W5500中文手册 iEthernet W5500 Datasheet 软件准备 需要安装好Keil - MDK及芯片对应的包,以

Mculover666的博客(嵌入式) 7387

AgentScope Java 入门:Spring AI Alibaba 与 AgentScope 的定位与区别

摘要:Spring AI Alibaba是阿里基于Spring AI开发的本地化AI应用框架,旨在服务Java开发者。它提供模型接入、函数调用、RAG等功能,并与阿里云基础设施深度集成。同时,阿里开源了多智能体框架AgentScope,其Java版(AgentScope-Java)专注于Agentic设计理念。两者将协同发展:Spring AI Alibaba侧重Spring生态集成,AgentScope-Java强化智能体能力。未来计划包括支持AgentScope、升级Admin平台,以及推进Server

SmartSi 1529

Java学习之集合类List、Set、Map

具体的关于ArrayList等实现类的介绍有时间再专门写篇文章,这里只是作简单介绍 集合类概述 集合类又被称为容器,和数组类似都能够存储一定的数据,但是又不一样。 常用的集合有List、Set、Map。其中接口List和Set继承了Collection接口,各接口还提供了不同的实现类。 在说常见集合之前,先提一下Collection类。Collection类是层次结构中的根接口。构...

秋水惊鸿的博客 389

深入理解SQL注入中的union select 1,2,3....

UNION 用于合并两个查询的结果集

渗透之路,攻防之间皆学问 2万+

java Map 集合类学习

了解最常用的集合类型之一 Map 的基础知识以及如何针对您应用程序特有的数据优化 Map。     java.util 中的集合类包含 Java 中某些最常用的类。 最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象元素列表。 List 适用于按数值索引访问元素的情形。    Ma

爱飞的蒲公英 594

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

学习-Java集合类之Map的TreeMap之特有方法的使用

第1关:学习-Java集合类之Map的TreeMap之特有方法的使用 任务描述 本关任务:使用 TreeMap 集合操作城市名以及城市编码。 相关知识 什么是 TreeMap TreeMap 是 Map 接口的实现类,它存储的元素是键值对(key-value)映射,其中 key 值不允许为 null,在添加、删除元素上,TreeMap 要比 HashMap 性能差。另外,它既是无序的,又是有序的。无序指的是存储元素顺序和输出顺序不同,有序指的是 TreeMap 会默认对元素的键进行自然排序(具体排

没事发发博客 5766

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【Java学习】java集合类map

Map 提供了一个更通用的元素存储方法。Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。从概念上而言,可以将 List 看作是具有数值键的 Map。而实际上,除了 List 和 Map 都在定义 java.util 中外,两者并没有直接的联系。 表 1:覆盖的方法。我们将这 Object 的这两个方法覆盖,以正确比较 Map 对象的等价性。 equa

lee_hust的专栏 502

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Java集合类Map与MapEntry学习

Map接口不是Collection接口的继承。Map接口用于维护键/值对(key/value pairs)。该接口描述了从不重复的键到值的映射。   (1) 添加、删除操作:   Object put(Object key, Object value): 将互相关联的一个关键字与一个值放入该映像。如果该关键字已经存在,那么与此关键字相关的新值将取代旧值。方法返回关键字的           旧

小白 2461

[Java学习之路篇] Java集合类库之Map接口

所在包:java.util 运用数据结构解决实际问题时,常常涉及到以空间换时间的问题,哈希表就能很好地解决此类问题,因为它检索快。而在java中已经有一个叫 Map 的接口及其实现类来归纳这些需要用到 键值对 Entry 的数据结构,方便开发人员根据需要来存储数据。 Map接口的常用方法有: 1、 添加元素 V put(K key, V value) 返回原来该位置的值 void putAll(Map<? extends K, ? extends V> m) 2、 删除元素 V remov

weixin_41887912的博客 357

Java集合类学习(四) Map集合

1 Map集合类型 1.1 Map 特点:存储的键值对映射关系,根据key可以找到value Map中所有的Key集合可以看做Set集合,无序、唯一 Map中所有Value的集合无序、不唯一 Set集合的底层就是Map,所以Set和Map的类型一致,也有HashMap、LinkedHashMap、TreeMap三种 1.2 HashMap • 采用Hashtable哈希表存储结构 • 优点:添加速度快 查询速度快 删除速度快 • 缺点:key无序 1.3 LinkedHashMap • 采用哈希

A20212的博客 200

第1关:学习-Java集合类之Map接口之学生花名册

Collection 接口下的所有子类只可以存储单值元素,倘若我们想要存储键值对元素(如:<张三,男>)到集合中,就必须使用 Map 接口下的实现类(如 HashMap 集合或者 TreeMap 集合)。Map 提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,我们可以根据 key(如:张三) 快速查找 value(如:男),其中键(key)值不可以重复,值(value)是可以重复的。

m0_73614626的博客 3937

传智播客java学习--集合类之Collections、map

今天我看了徐文海老师讲的集合类视频,对讲课内容做了简单的记录;许老师是这样讲的  集合类的使用集合(或容器)是代表一个对象组的单个对象,其它对象被认为是它的元素。集合用于处理多种类型对象的问题,所有的类型都有一个特殊的种类(也就是说,它们都是从一个共同父类继承来的)。Java编程语言支持集合Vector,List,Map,Stack等等。例如,Stack实现后进先出(LIFO)

398

Java集合类的学习(五)——Map

1.4         Map  1.4.1        概述 数学中的映射关系在Java中就是通过Map来实现的。它表示,里面存储的元素是一个对(pair),我们通过一个对象,可以在这个映射关系中找到另外一个和这个对象相关的东西。 前面提到的我们对于根据帐号名得到对应的人员的信息,就属于这种情况的应用。我们讲一个人员的帐户名和这人员的信息作了一个映射关系,也就是说,我们把帐户名和人员信息

Jmark 1424

Java学习路线(14)——Map集合类

Java学习路线(14)——Map集合类

Zain_horse的博客 1399

java储存键值对的集合_java基础学习(11)JAVA 集合类List、Set和Map

1.集合堆栈和队列数据结构的特点:堆栈数据结构先进后出,后进先出;队列结构是先进先出,后进后出。1.1 什么是集合存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式。集合的出现就是为了持有对象。集合中可以存储任意类型的对象,而且长度可变。在程序中有可能无法预先知道需要多少个对象, 那么用数组来装对象的话, 长度不好定义,...

weixin_34511324的博客 4136

8.6 学习-Java集合类之Map接口之学生花名册

任务描述 本关任务:把给定的学生花名册数据添加到 Map 集合中。 相关知识 在 Java 的集合体系中,主要包含 Collection 接口以及 Map 接口,本实训将介绍 Map 接口相关知识。

m0_65745343的博客 828

集合类(List、Map、Set)(JAVA学习第六弹)

1.List集合 List集合除了继承Collection接口,还定义了以下两个方法: get(int index);//获取集合中第index个元素 set(int index, Object obj);//将集合中index位置的对象改成指定对象 List接口实现类有:ArrayList、LinkedList ArrayList: 实现可变长度的数组,方便对特定索引位置的数据快速访问...

sunying1994的博客 221
上一篇: Java集合类学习--ArrayBlockingQueue
下一篇: Java集合类学习--PriorityQueue
CodersCoder
博客等级 码龄10年 90粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值