当前位置: 首页 > news >正文

Map 不常用方法介绍

getOrDefault

尝试获取key对应的值,如果未获取到,就返回默认值。
例子:

private static void testGetOrDefault() {Map<String, String> map = new HashMap<>(4);map.put("123", "123");String key = "key";String defaultValue = "defaultValue";// 老写法String oldValue = defaultValue;if (map.containsKey(key)) {oldValue = map.get(key);}System.out.println("oldValue = " + oldValue);// 新写法String newValue = map.getOrDefault(key, defaultValue);System.out.println("newValue = " + newValue);
}

foreach

遍历map的数据使用的。如果没有foreach,我们遍历map的时候一般是使用增强for循环,有了这个方法后,可以更加方便使用entry中的key和val:

private static void testForeach() {Map<String, String> map = new HashMap<>(4);map.put("123", "123");// 老写法for (Map.Entry<String, String> entry : map.entrySet()) {System.out.printf("老写法 key = %s, value = %s%n", entry.getKey(), entry.getValue());}// 新写法map.forEach((key, value) -> System.out.printf("新写法 key = %s, value = %s%n", key, value));
}

merge

从名字可以想到,是合并entry使用的,但是具体是怎么合并呢?看一下日常最常用的Map实现类HashMap对merge方法的实现:

@Override
public V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction) {if (value == null || remappingFunction == null)throw new NullPointerException();int hash = hash(key);Node<K,V>[] tab; Node<K,V> first; int n, i;int binCount = 0;TreeNode<K,V> t = null;Node<K,V> old = null;if (size > threshold || (tab = table) == null ||(n = tab.length) == 0)n = (tab = resize()).length;if ((first = tab[i = (n - 1) & hash]) != null) {if (first instanceof TreeNode)old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key);else {Node<K,V> e = first; K k;do {if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k)))) {old = e;break;}++binCount;} while ((e = e.next) != null);}}if (old != null) {V v;if (old.value != null) {int mc = modCount;v = remappingFunction.apply(old.value, value);if (mc != modCount) {throw new ConcurrentModificationException();}} else {v = value;}if (v != null) {old.value = v;afterNodeAccess(old);}elseremoveNode(hash, key, null, false, true);return v;} else {if (t != null)t.putTreeVal(this, tab, hash, key, value);else {tab[i] = newNode(hash, key, value, first);if (binCount >= TREEIFY_THRESHOLD - 1)treeifyBin(tab, hash);}++modCount;++size;afterNodeInsertion(true);return value;}
}

代码比较长,但是实现的效果比较容易描述:这个方法接收3个参数:key、value、function。

  • 如果key存在,将value按照function做1次计算后,更新到Map中
  • 如果key不存在,将key-value放入Map中

这个方法在某些场景中挺好用的,代码简洁易懂,例如:我们有1个List,要统计List中每个元素出现的次数。我们要实现的逻辑是,遍历List中的每个元素,如果这个元素在Map中存在,Map中的值+1;如果不存在,则放入Map中,次数(值)为1。

private static void testMerge() {Map<String, Integer> cntMap = new HashMap<>(8);List<String> list = Arrays.asList("apple", "orange", "banana", "orange");// 老写法for (String item : list) {if (cntMap.containsKey(item)) {cntMap.put(item, cntMap.get(item) + 1);} else {cntMap.put(item, 1);}}// 新写法for (String item : list) {cntMap.merge(item, 1, Integer::sum);}
}

可以看到我们使用merge方法的话,只用1行就简洁实现了这个逻辑。

putIfAbsent

不存在key或者值为null时,才将键值对放入Map。跟put方法相比,这个方法不会直接覆盖已有的值,在不允许覆盖旧值的场景使用起来会比较简洁。

private static void testPutIfAbsent() {Map<String, Integer> scoreMap = new HashMap<>(4);scoreMap.put("Jim", 88);scoreMap.put("Lily", 90);// 老写法if (!scoreMap.containsKey("Lily")) {scoreMap.put("Lily", 98);}// 新写法scoreMap.putIfAbsent("Lily", 98);
}

computer

computer方法需要传入2个参数:key、function。主要有3步操作

  • 获取到key对应的oldValue,可能为null
  • 经过function计算获取newValue
  • put(key, newValue)

还是以刚刚统计单次次数需求为例,看一下computer的写法:

private static void testComputer() {Map<String, Integer> cntMap = new HashMap<>(8);List<String> list = Arrays.asList("apple", "orange", "banana", "orange");// 老写法for (String item : list) {if (cntMap.containsKey(item)) {cntMap.put(item, cntMap.get(item) + 1);} else {cntMap.put(item, 1);}}// 新写法for (String item : list) {cntMap.compute(item, (k, v) -> {if (v == null) {v = 1;} else {v += 1;}return v;});}
}

computeIfAbsent

看名字就知道是compute方法衍生出来的方法,这个方法只在key不存在的时候,执行computer计算,如果说key对应的value存在,就直接返回这个value。

例如,我们需要计算斐波那锲数列的时候,可以使用这个方法来简化代码:

private static void testComputerIfAbsent() {Map<Integer, Integer> fabMap = new ConcurrentHashMap<>(16);fabMap.put(0, 1);fabMap.put(1, 1);System.out.println(fab(5, fabMap));
}private static Integer fab(Integer index, Map<Integer, Integer> fabMap) {return fabMap.computeIfAbsent(index, i -> fab(i - 2, fabMap) + fab(i - 1, fabMap));
}

computeIfPresent

这个是computeIfAbsent的姊妹方法,区别在于,这个方法是只有key存在的时候,才去执行computer计算和值的更新。

replace

这个方法的效果是:

  • 如果key存在,则更新值
  • 如果key不存在,什么也不做

相关文章:

Map 不常用方法介绍

getOrDefault 尝试获取key对应的值&#xff0c;如果未获取到&#xff0c;就返回默认值。 例子&#xff1a; private static void testGetOrDefault() {Map<String, String> map new HashMap<>(4);map.put("123", "123");String key "…...

论文翻译:ICLR 2024.DETECTING PRETRAINING DATA FROM LARGE LANGUAGE MODELS

文章目录 检测大型语言模型的预训练数据摘要1 引言2 预训练数据检测问题2.1 问题定义和挑战2.2 WIKIMIA&#xff1a;动态评估基准 3 MIN-K% PROB&#xff1a;简单的无参考预训练数据检测方法4 实验4.1 数据集和指标4.2 基线检测方法4.3 实现和结果4.4 分析 5 案例研究&#xff…...

Spring 框架精髓:从基础到分布式架构的进阶之路

一、概述 &#xff08;一&#xff09;Spring框架概念 1.概念&#xff1a; Spring框架是一个用于简化Java企业级应用开发的开源应用程序框架。 2.Spring框架的核心与提供的技术支持&#xff1a; 核心&#xff1a; IoC控制反转|反转控制&#xff1a;利用框架创建类的对象的…...

深入理解C++ Lambda表达式:语法、用法与原理及其包装器的使用

深入理解C Lambda表达式&#xff1a;语法、用法与原理及其包装器的使用 lambda表达式C98中的一个例子lambda表达式语法lambda表达式各部分说明捕获列表说明 函数对象与lambda表达式 包装器function包装器 bind &#x1f30f;个人博客主页&#xff1a; 个人主页 本文深入介绍了…...

C# 编程语言:跨时代的革命

C# 是一种由微软开发的现代、类型安全、面向对象的编程语言&#xff0c;自2000年推出以来&#xff0c;它已经成为.NET平台的核心组成部分。在本文中&#xff0c;我们将探讨C#语言的特点、优势以及它在软件开发领域中的应用。 C# 语言特点 类型安全和自动垃圾回收 C# 是一种类…...

恋爱脑学Rust之Box与RC的对比

在遥远的某个小镇&#xff0c;住着一对年轻的恋人&#xff1a;阿丽和小明。他们的爱情故事就像 Rust 中的 Rc 和 Box 智能指针那样&#xff0c;有着各自不同的「所有权」和「共享」的理解。 故事背景 阿丽和小明准备共同养一株非常珍贵的花&#xff08;我们称之为“心之花”&…...

Rust 力扣 - 1423. 可获得的最大点数

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 题目所求结果存在下述等式 可获得的最大点数 所有卡牌的点数之和 - 长度为&#xff08;卡牌数量 - k&#xff09;的窗口的点数之和的最小值 我们遍历长度为&#xff08;卡牌数量 - k&#xff09;的窗口&#…...

Android15音频进阶之Cuttlefish搭建音频开发环境(九十二)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…...

发现不为人知的AI宝藏:发现AI新天地! —— 《第八期》

在人工智能&#xff08;AI&#xff09;领域&#xff0c;尽管ChatGPT、Midjourney等知名产品广为人知&#xff0c;但还有许多小众而有趣的AI工具等待你的探索。本文将推荐五款实用的AI工具&#xff0c;它们不仅功能强大&#xff0c;而且使用简单&#xff0c;帮助你在各种场景中提…...

基于物联网设计的地下煤矿安全监测与预警

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成 1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发 1.5 模块的技术详情介绍【1】NBIOT-BC26模块【2】MQ5传感器【4】DHT11传感器【5】红外热释电人体检…...

Java 23 的12 个新特性!!

Java 23 来啦&#xff01;和 Java 22 一样&#xff0c;这也是一个非 LTS&#xff08;长期支持&#xff09;版本&#xff0c;Oracle 仅提供六个月的支持。下一个长期支持版是 Java 25&#xff0c;预计明年 9 月份发布。 Java 23 一共有 12 个新特性&#xff01; 有同学表示&…...

.NET 8 中 Entity Framework Core 的使用

本文代码&#xff1a;https://download.csdn.net/download/hefeng_aspnet/89935738 概述 Entity Framework Core (EF Core) 已成为 .NET 开发中数据访问的基石工具&#xff0c;为开发人员提供了强大而多功能的解决方案。随着 .NET 8 和 C# 10 中引入的改进&#xff0c;开发人…...

ai数字人分身123口播克隆数字人小程序源码_博纳软云

功能配置 一、用户 用户管理小黑屋用户反馈登录设置短信参数 二、作品 视频作品背景音乐库背景音乐分类 三、形象分身 上传记录视频要求参数配置 四、声音克隆 克隆记录参数配置声音要求文案示例 五、AI文案 生成记录创作模型模型分类Al配置 六、充值 充值订单积分套…...

从0开始学PHP面向对象内容之(类,对象,构造/析构函数)

上期我们讲了面向对象的一些基本信息&#xff0c;这期让我们详细的了解一下 一、面向对象—类 1、PHP类的定义语法&#xff1a; <?php class className {var $var1;var $var2 "constant string";function classfunc ($arg1, $arg2) {[..]}[..] } ?>2、解…...

openGauss数据库-头歌实验1-5 修改数据库

一、查看表结构与修改表名 &#xff08;一&#xff09;任务描述 本关任务&#xff1a;修改表名&#xff0c;并能顺利查询到修改后表的结构。 &#xff08;二&#xff09;相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 1.如何查看表的结构&#xff1b; 2.如…...

《JVM第3课》运行时数据区

无痛快速学习入门JVM&#xff0c;欢迎订阅本免费专栏 运行时数据区结构图如下&#xff1a; 可分为 5 个区域&#xff0c;分别是方法区、堆区、虚拟机栈、本地方法栈、程序计数器。这里大概介绍一下各个模块的作用&#xff0c;会在后面的文章展开讲。 类加载子系统会把类信息…...

阅读笔记 Contemporary strategy analysis Chapter 14

来源&#xff1a;Robert M. Grant - Contemporary strategy analysis (2018) Chapter 14 External Growth Strategies: Mergers, Acquisitions, and Alliances 合并、收购和联盟 Ⅰ Introduction and Objectives 企业并购与联盟是公司实现快速扩张的重要战略工具。通过这些手段…...

2024网鼎杯青龙组wp:Crypto2

题目 附件内容如下 # coding: utf-8 #!/usr/bin/env python2import gmpy2 import random import binascii from hashlib import sha256 from sympy import nextprime from Crypto.Cipher import AES from Crypto.Util.Padding import pad from Crypto.Util.number import long…...

能通过Ping命令访问CentOS 9 Stream,但在使用Xshell连接

能通过Ping命令访问CentOS 9 Stream&#xff0c;但在使用Xshell进行SSH连接失败 1. **确认SSH服务状态**&#xff1a;2. **检查SSH配置**&#xff1a;要检查和设置PermitRootLogin选项&#xff0c;您需要编辑SSH配置文件/etc/ssh/sshd_config。以下是具体步骤&#xff1a;1. 打…...

Oracle 第19章:高级查询技术

在Oracle数据库中&#xff0c;高级查询技术是数据库管理员和开发人员必须掌握的重要技能。这些技术能够帮助优化查询性能&#xff0c;简化复杂的查询逻辑&#xff0c;并提高数据处理的效率。本章将重点讨论两个关键概念&#xff1a;子查询和连接与并集操作。 子查询 定义: 子…...

Excel:vba运行时错误“7“:内存溢出错误

我这里出现这个错误是在批注中插入图片时报错 原因:我插入的图片不都是jpg的类型的&#xff0c;但是其中的两张图片是webp类型的&#xff0c;但是我把文件后缀名修改成了jpg&#xff0c;以为变成了jpg类型的图片&#xff0c;但是图片在批注里面无法显示&#xff0c;所以运行到第…...

【MyBatis源码】BoundSql分析

基础 BoundSql是对SQL语句及参数信息的封装&#xff0c;它是SqlSource解析后的结果。Executor组件并不是直接通过StaticSqlSource对象完成数据库操作的&#xff0c;而是与BoundSql交互。BoundSql是对Executor组件执行SQL信息的封装&#xff0c;具体实现代码如下&#xff1a; …...

KTHREAD--InitialStack和KernelStack和TSS的esp0

InitialStack和TSS.esp0的关系,在这里可以看到 mov ecx, [esi_KTHREAD.InitialStack] ; esi: newthread lea eax, [ecx-210h] ; 越过FPXSAVE指令存储地址 test byte ptr [eax-1Ah], 2 ; 判断efalgs寄存器的VIF位是否为1 jnz short loc_458743 sub eax, 10h…...

Skia基础运用(Ubuntu环境下使用BUILD.gn)

1.拉取代码 git clone https://skia.googlesource.com/skia python tools/git-sync-deps // 这一步可能会出现部分错误&#xff0c;再次执行直到成功 // 这里面拉取完三方库之后会拉取node&#xff0c;linux等压缩包&#xff0c;从google下载上面执行完&#xff0c;代码就完全…...

Vue中props和data的优先级哪个更高?

前言 Vue组件之间的数据传递是一个非常重要的环节。而在组件内部&#xff0c;我们经常会用到props和data来管理和传递数据。那么&#xff0c;问题来了&#xff1a;当props和data有冲突时&#xff0c;哪个优先级更高呢&#xff1f; 为了更好地理解这个问题&#xff0c;我们先来…...

springboot2.x使用SSE方式代理或者转发其他流式接口

文章目录 1.需求描述2.代码2.1.示例controller2.2.示例service2.3.示例impl 3.测试 1.需求描述 使用SSE的方式主要还是要跟前端建立一个EventSource的链接&#xff0c;有了这个连接&#xff0c;然后往通道里写入数据流&#xff0c;前端自然会拿到流式数据&#xff0c;写啥拿啥…...

consul入门教程

一、介绍Consul Consul是由HashiCorp开发的一种服务发现和配置管理工具&#xff0c;它可以提供分布式系统所需的多个关键功能&#xff0c;如服务发现、配置管理、键值存储等。Consul可以帮助开发人员轻松构建分布式系统&#xff0c;提高系统的可靠性和可扩展性。 二、Consul实…...

软考:大数据架构设计

大数据总结 大数据处理系统的特征 1、鲁棒性和容错性 2、低延迟读取和更新能力 3、横向扩容 4、通用性 5、延展性 6、即席查询能力 7、最少维护能力 8、可调试性 Lambda架构 批处理层 存储数据集和生成Batch View 管理主数据集&#xff0c;原始的&#xff0c;不可变的&…...

token无感刷新+处理并发的后端方案

问题描述&#xff1a; 当用户通过登陆后进入一个web网站&#xff0c;会把token保存到localStorage。假设token过期时间30min。 那么当用户在网站快乐地玩耍了30min后&#xff0c;这时进行了一次提交表单&#xff0c;它会被重定向到登陆页面。 作为用户&#xff1a;我表单填了…...

【系统设计】让 Java “动起来”:动态语言与静态语言的比较及 DSL 实现

在编程语言的世界里&#xff0c;语言的特性决定了它们在不同场景下的适用性。动态语言和静态语言是两种常见的编程范式&#xff0c;它们的差异不仅影响开发者的使用习惯&#xff0c;还决定了它们在某些应用场景中的表现。在这篇博文中&#xff0c;我们将通过Python和Java这两种…...