Map你只会用put,get?试试这些高级方法

文摘   2024-11-19 08:01   新疆  

最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。

环境:Java 8 / 21



1. 简介

在Java中,Map接口远不止putget这两个基本操作,它实际上是一个功能丰富且高度可扩展的集合框架组件。Map主要用于存储键值对(key-value pairs),其中每个键都是唯一的,并且与一个值相关联。

如果你还仅仅是只知道Map中的put和get方法,那么你的Java集合框架知识还有很大的提升空间。从java8开始对Map新增了很多强大的方法,接下来我们就分别详细的介绍这些方法。

2. 实战案例

初始数据

private static Map<String, String> map = new HashMap<>() ;static {  map.put("a", "aaa") ;  map.put("b", "bbb") ;}

接下来,我们就基于上面的Map集合进行新功能的操作。

2.1 getOrDefault

返回指定key映射到的值,如果该映射表不包含键的映射,则返回 defaultValue。如下示例:

public static void getOrDefault() {  String value = map.getOrDefault("c", "ccc") ;  System.out.println(value) ;}// 输出:ccc

当给定的key不存在时,返回给定的默认值。

2.2 forEach

对每个条目执行给定的操作,直到此映射中的所有条目都已处理或操作抛出异常为止。简单说就是遍历集合中的元素。

public static void forEach() {  map.forEach((key, value) -> System.out.println(key + "@" + value)) ;}

其内部实现还是通过for循环,在循环体中调用我们这里传入的参数

public void forEach(BiConsumer<? super K, ? super V> action) {  for (Node<K,V> e = tab[i]; e != null; e = e.next)    action.accept(e.key, e.value);}

省去我们写for语句。

2.3 replaceAll

将每个条目(entry)的值替换为对该条目调用给定函数的结果,直到所有条目都已处理或函数抛出异常为止。

public static void replaceAll() {  map.replaceAll((key, value) -> "new - " + value) ;  System.out.println(map) ;}// 输出结果:{a=new - aaa, b=new - bbb}

将所有key对应的值都进行了修改。

还有对应的replace(key, value) 与 replace(key, oldValue, newValue)方法

public static void replace() {  map.replace("a", "new - " + map.get("a")) ;  System.out.println(map) ;}// 输出结果:{a=new - aaa, b=bbb}public static void replace2() {  map.replace("a", "aaa", "new - aaa") ;  System.out.println(map) ;}// 输出结果:{a=new - aaa, b=bbb}   // 只有给定的key/value都匹配才会替换

只会替换给定的key或(key/value)对应的值。

2.4 putIfAbsent

如果指定的key尚未与一个值关联(或映射为null),则将其与给定的值关联,并返回null;否则,返回当前值。

public static void putIfAbsent() {  String ret = map.putIfAbsent("c", "ccc") ;  System.out.println("ret = " + ret + ", " + map) ;}// 输出结果:ret = null, {a=aaa, b=bbb, c=ccc}

如果这里指定的c存在,但是值为null,那么也会进行修改替换为ccc,而返回null。

2.5 remove(key, value)

只有在指定键当前映射到指定值时,才删除指定键的条目。

public static void remove() {  boolean ret = map.remove("a""aaa") ;  System.out.println("ret = " + ret + ", " + map) ;}// 输出结果:ret = true, {b=bbb}

如上示例,如果给定的value不匹配,那么也不会删除。

2.6 computeIfAbsent

如果指定的key未与一个值关联(或映射为null),则尝试使用给定的映射函数计算其值,并将其加入此Map中,除非计算结果为null。如果函数返回null,则不记录任何映射。

public static void computeIfAbsent() {  String ret = map.computeIfAbsent("c", key -> "ccc") ;  System.out.println("ret = " + ret + ", " + map) ;}// 输出结果:ret = ccc, {a=aaa, b=bbb, c=ccc}

如果这里给定的key已经存在,则返回的是key对应的value。

2.7 computeIfPresent

如果指定key对应的值存在且不为null,则尝试根据该key及其当前映射的值计算一个新的映射。如果函数返回null,则移除映射。

public static void computeIfPresent() {  String ret = map.computeIfPresent("a", (key, value) -> "aaa666") ;  System.out.println("ret = " + ret + ", " + map) ;}// 输出结果:ret = aaa666, {a=aaa666, b=bbb}

如果这里给定的函数返回值为null,那么将移除对应的key(如:这里的a);如下示例:

public static void computeIfPresent() {  String ret = map.computeIfPresent("a", (key, value) -> null) ;  System.out.println("ret = " + ret + ", " + map) ;}// 输出结果:ret = null, {b=bbb}

函数返回了null,则将key=a从map中删除。

2.8 compute

为给定的key,根据给定的函数计算新的值,然后替换。如果函数返回null,则对应的删除指定的key。

public static void compute() {  String ret = map.compute("a", (key, value) -> "xxxooo") ;  System.out.println("ret = " + ret + ", " + map) ;}// 输出结果:ret = xxxooo, {a=xxxooo, b=bbb}

如上上面的函数返回了null,则会将对应的key从map中删除。

2.9 merge

如果给定的key存在,则通过函数计算新的值,而函数接收的2个参数分别是:旧值,新值(方法的第二个参数),如下示例:

public static void merge() {  String ret = map.merge("a", "xxxooo",     (oldValue, value) -> oldValue + "@" + value) ;  System.out.println("ret = " + ret + ", " + map) ;}// 输出结果:ret = aaa@xxxooo, {a=aaa@xxxooo, b=bbb}

如果这里的函数返回了null,那么将给定的key 删除。

下面几个方法是Java9添加的

2.10 of

该方法是个静态的方法(Map接口中定义),通过of能快捷定义Map集合元素,但是返回的Map集合是不可变的,也就是你不能新增,删除,修改操作。

public static void of() {  Map<String, String> map = Map.of("a", "aaa", "b", "bbb") ;  System.out.println(map) ;  map.remove("a") ; // throw UnsupportedOperationException  map.put("c", "ccc") ;// throw UnsupportedOperationException  map.replace("a", "xxxooo") ;// throw UnsupportedOperationException}// 输出结果:{b=bbb, a=aaa}

切记,of操作返回的是不可变集合。

2.11 ofEntries

与of一样,该方法返回的也是不可变的集合

public static void ofEntries() {  Map<String, String> map = Map.ofEntries(Map.entry("a", "aaa"), Map.entry("b", "bbb")) ;  System.out.println(map) ;}// 输出结果:{b=bbb, a=aaa}

该方法参数是可变长参数。

2.12 copyOf

返回一个包含给定Map集合的不可修改Map。

public static void copyOf() {  Map<String, String> ret = Map.copyOf(map) ;  ret.put("c", "ccc") ;// throw UnsupportedOperationException  System.out.println(ret) ;}

注意:如果我们的参数本身就是不可变的Map,那么将直接返回。如果我们集合是空(无元素),则返回一个空的不可变集合。否则,内部通过ofEntries复制数据。

以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

不写一行代码通过UI界面配置HTTP接口

速看!Spring Boot任务调度你不知道的使用技巧

Spring Boot基于Redis实现高效的消息通信

性能提升!Spring Boot使用Guava中3大神技

必学!Spring Boot结合MDC全方位的日志跟踪(支持跨线程)

实体与DTO如何转换?这个工具很厉害

提升性能:Java工程师必备的20条SQL最佳实践

自己动手实现精简版SpringBoot原来如此简单

真香!Forest让HTTP请求如此简单

一文彻底玩转@RequestMapping,高级用法你未必知道

别不信@PathVariable你真不会用

总结7种JVM出现OOM时的原因及解决方案

强大!SpringBoot通过3种方式实现AOP切面,第三种方式性能极佳

必须掌握的SpringBoot开发技能

Java开发人员必须掌握的11种干净代码最佳实践

Spring全家桶实战案例源码
spring, springboot, springcloud 案例开发详解
 最新文章