【JAVA8】Map新方法,别再重复造车轮了


java8 发布后,map类库增加了多个新的方法,利用这些新方法能更加便利地操纵Map中的数据

新增的方法有:

getOrDefault,forEach,compute,computeIfAbsent,computeIfPresent,merge,putIfAbsent,remove(key,value),replace,replaceAll

getOrDefault

getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。

语法:

hashmap.get(Object key, V defaultValue)

参数说明:

  • key - 键
  • defaultValue - 当指定的key并不存在映射关系中,则返回的该默认值

返回值:

返回 key 相映射的的 value,如果给定的 key 在映射关系中找不到,则返回指定的默认值。

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);

java8之前的方式

Map<String, Integer> map = new HashMap<>(4);
map.put("lisa", 1);
int lisaValue = 0;
if (map.containsKey("lisa")) {
    lisaValue = map.get("lisa");
}
System.out.println(lisaValue);

java8

// key为 lisa 的映射存在则返回对应value,否则返回默认值-1
Integer java8lisaValue = map.getOrDefault("lisa", -1);
// 1
System.out.println(java8lisaValue);
// key为 adas 的映射存在则返回对应value,否则返回默认值-999
Integer adasValue = map.getOrDefault("adas", -999);
// adas
System.out.println(adasValue);

forEach

foreach 可以让我们以Lambda的方式快速遍历映射集(map)

语法:

map.forEach(BiConsumer<K, V> action)

参数说明:

  • BiConsumer- java8新提供的函数式接口,我们可以定义遍历消费逻辑

返回值:

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);

java8之前的方式

这种是以前Map遍历获取键值对信息最高效的方式,因为每组键值对只需遍历一次,但写法较为古老

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + "==" + entry.getValue());
}

java8

实际上Java8 map的foreach底层仍是用的entrySet,只是上层用了BiConsumer 函数式接口,简化了我们直接遍历的代码。

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

具体实现如下:

image-20210905104814367

compute

尝试计算指定键及其当前映射值的映射(如果没有当前映射,则返回null)

公式:

map.compute(K key, BiFunction remappingFunction)

参数说明:

  • key - 键
  • remappingFunction - 重新映射函数,用于重新计算值

返回值

如果 key 对应的 value 不存在,则返回该 null,如果存在,则返回通过 remappingFunction 重新计算后的值并保存到映射集中(如重新计算后的值为Null,不会保存,且会将该映射从映射集中删除)

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);

java8 之前操作

private static Integer computeBefore(String key, Integer newValue) {
    Map<String, Integer> map = new LinkedHashMap<>(4);
    map.put("lisa", 1);
    map.put("jone", 2);
    map.put("selina", 3);
    Integer oldValue = map.get(key);
    if (newValue != null) {
        if (map.containsKey(key) && oldValue != null) {
            map.remove(key);
        }
        return null;
    } else {
        map.put(key, newValue);
        return newValue;
    }
}

java8操作

Key在Map中存在

// jone key存在,且 新value不为null,则会返回最新jone对应的value (v + 234),并添加到映射集map中
Integer joneNewValue = map.compute("jone", (k, v) -> v == null ? 0 : v + 234);
// joneNewValue:236
System.out.println("joneNewValue:" + joneNewValue);
// {lisa=1, jone=236, selina=3}
System.out.println(map);

System.out.println("================");
// jone key存在,且 新value为null,则会返回最新jone对应的value null,并将映射在原集中删除
Integer joneNewValue2 = map.compute("jone", (k, v) -> null);
// joneNewValue2:null
System.out.println("joneNewValue2:" + joneNewValue2);
// 此时会 移除 KEY  jone
// {lisa=1, selina=3}
System.out.println(map);

Key在Map中不存在

// asd key不存在,且 新value不为null,则会返回最新asd对应的value 111,并保存到映射集map中
Integer asdNewValue = map.compute("asd", (k, v) -> 111);
// asdNewValue:111
System.out.println("asdNewValue:" + asdNewValue);
// {lisa=1, selina=3, asd=111}
System.out.println(map);

System.out.println("================");
// box key不存在,且 新value为null,则会返回null, 不保存到映射集map中
Integer boxNewValue = map.compute("box", (k, v) -> null);
// boxNewValue:null
System.out.println("boxNewValue:" + boxNewValue);
// {lisa=1, selina=3, asd=111}
System.out.println(map);

computeIfAbsent

如果指定的KEY 的键值对(k,v)不存在,或者 对应的Value 为空,则将键值对新增至映射集(Map)中

语法:

map.computeIfAbsent(K key, Function remappingFunction)

参数说明:

  • key - 键
  • remappingFunction - 重新映射函数,用于重新计算值

返回值:

如果 key 对应的 value 不存在,则使用获取 remappingFunction 重新计算后的值,并保存为该 key 的 value,否则返回 value。

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);
map.put("ddd", null);

java8 之前操作

Integer lisaValue = map.get("adas");
if ( !map.containsKey("adas")|| map.get("adas") == null) {
    map.put("adas", 2345);
}

java8操作

// 原映射集无 key为 adas的键值对,且 新key  adas 对应的 value 不为null (2345) 则会将其添加到map映射集中并返回该值
Integer adas = map.computeIfAbsent("adas", x -> 2345);
// 2345
System.out.println(adas);
// {lisa=1, jone=2, selina=3, ddd=null, adas=2345}
System.out.println(map);

System.out.println("--------------");

// 原映射集无 key为 dml的键值对,且 新key  ml 对应的 value 为null,则忽略添加,并返回null
Integer dmlValue = map.computeIfAbsent("dml", x -> null);
// null
System.out.println(dmlValue);
// {lisa=1, jone=2, selina=3, ddd=null, adas=2345}
System.out.println(map);

System.out.println("--------------");
// 原映射集有 Key为 ddd的键值对,但ddd对应的value 为空,如果我们再次添加有效value到ddd,则会将原键值对覆盖
Integer dddNewValue = map.computeIfAbsent("ddd", x -> 0);
// 0
System.out.println(dddNewValue);
// {lisa=1, jone=2, selina=3, ddd=0, adas=2345}
System.out.println(map);

computeIfPresent

如果指定KEY的映射存在且Value非null,则将指定KEY的原Value,替换为现在的Value,保存存在映射集中,如果现Value为null,会将指定KEY的映射删除

语法:

map.computeIfPresent(K key, BiFunction remappingFunction)

参数说明:

  • key - 键
  • remappingFunction - 重新映射函数,用于重新计算值

返回值:

如果 key 对应的 value 不存在,则返回该 null,如果存在,则返回通过 remappingFunction 重新计算后的值。

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);
map.put("ddd", null);

java8之前操作

if (map.get("selina") != null) {
    Integer oldValue = map.get("selina");
    Integer newValue = 1232312;
    if (newValue != null) {
        map.put("selina", newValue);
    } else {
        map.remove("selina");
    } 
}

java8

// 原映射集中存在对应KEY  ,原Value不为null,现value不为null,则覆盖原来 键值对映射
Integer selinaNewValue = map.computeIfPresent("selina", (k, v) -> 888999);
// 888999
System.out.println(selinaNewValue);
// {lisa=1, jone=2, selina=888999, ddd=null}
System.out.println(map);

System.out.println("-------------------");
// 原映射集中存在对应KEY  ,原Value不为null,现value为null,则移除对应键值对
Integer selinaNewValue2 = map.computeIfPresent("selina", (k, v) -> null);
// null
System.out.println(selinaNewValue2);
// 移除了selina
System.out.println(map);

System.out.println("-------------------");
// 原映射集中存在对应KEY  ,原Value为null,现value 不为null,  对原映射集不做任何操作
Integer dddNewValue = map.computeIfPresent("ddd", (k, v) -> 2222222);
System.out.println(dddNewValue);
System.out.println(map);

System.out.println("-------------------");
// 原映射集中不存在对应KEY  ,现value 不为null  对原映射集不做任何操作
Integer mqNewValue = map.computeIfPresent("mq", (k, v) -> -1);
System.out.println(mqNewValue);
System.out.println(map);

merge

merge() 方法会先判断指定的 key 是否存在,如果不存在,则添加键值对到 hashMap 中,如果存在则根据逻辑重新映射该KEY键值对(如何合并相同KEY的新旧VALUE)

语法:

map.merge(key, value, remappingFunction)

参数说明:

  • key - 键
  • value - 值
  • remappingFunction - 重新映射函数,用于重新计算值

返回值:

如果 key 对应的 value 不存在,则返回该 value 值,如果存在,则返回通过 remappingFunction 重新计算后的值。

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);
map.put("ddd", null);

我们都知道,Map 的KEY,如果相同了,后插入的值会覆盖新的值

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);
// {lisa=1, jone=2, selina=3}
System.out.println(map);
map.put("lisa", 2);
// {lisa=2, jone=2, selina=3}
System.out.println(map);

merge,可以让我们根据自己选择如何处理相同KEY的值,类似于冲突合并(怎么合并,自己决定)

// 采用旧值
map.merge("lisa", 100, (oldValue, newValue) -> oldValue);

// 采用新值
map.merge("lisa", 100, (oldValue, newValue) -> newValue);

// 新旧值逻辑处理合并
map.merge("lisa", 100, (oldValue, newValue) -> oldValue + newValue);
  map.merge("lisa", 100, Integer::sum);

注意:

java8 Stream Collectors.toMap() 方法便要我们去合并冲突,否则如果出现相同KEY的数据,或者Value为null,程序会报错!

User adas = new User("adas", 23);
User adas2 = new User("adas", 28);
User mlg = new User("mlg", 34);
ArrayList<User> list = new ArrayList<>();
list.add(adas);
list.add(adas2);
list.add(mlg);
Map<String, Integer> userMap = list.stream().collect(Collectors.toMap(User::getName, User::getValue));
System.out.println(userMap);

提示我们键冲突了!

image-20210905135211281

解决:

Map<String, Integer> userMap = list.stream()
        .filter(x->x.name!=null && x.value!=null)
        // 这里采用新值覆盖旧值
        .collect(Collectors.toMap(User::getName, User::getValue,(oldValue,newValue)->newValue));
// {adas=28, mlg=34}
System.out.println(userMap);

putIfAbsent

putIfAbsent() 方法会先判断指定的键(key)是否存在,不存在则将键/值对插入到映射集中,并返回null,存在则返回原本Value

语法:

map.putIfAbsent(K key, V value)

参数说明:

  • key - 键
  • value - 值

返回值:

如果所指定的 key 已经在Map 中存在,返回和这个 key 值对应的 value, 如果所指定的 key 在Map 中不存在,则返回 null。

注意如果指定 key 之前已经和一个 null 值相关联了 ,则该方法也返回 null。

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);

java8 之前写法

Integer newValue = 222;
Integer joneValue = map.get("jone");
if (joneValue == null) {
    joneValue = map.put("lisa", newValue);
} else {
    joneValue = joneValue;
} 

java8

// selina 在源映射集中不存在,则返回null 做插入操作
Integer adasValue = map.putIfAbsent("adas", 1);
System.out.println(adasValue);
System.out.println(map);

System.out.println("----------");

// selina 在源映射集中存在,则返回原值 不做插入操作
Integer selinaValue = map.putIfAbsent("selina", 33333);
System.out.println(selinaValue);
System.out.println(map);

remove(key,value)

当指定的 KEY 与VALUE 在映射集中存在,且为绑定的键值对关系时,才移除

语法:

map.remove(K key, V value)

参数说明:

  • key - 键
  • value - 值

返回值:

仅当 key-value 映射存在,且二者为绑定关系时,才会移除该数据,返回true,其他情况为false

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);

演示

// lisa-2 无映射关系,因为不会移除
map.remove("lisa", 2);
// {lisa=1}
System.out.println(map);

replace

replace() 方法替换 映射集中是指定的 key 对应的 value。

语法:

map.replace(K key, V oldValue, V newValue)

参数说明:

  • key - 键
  • oldValue - 旧的 value 值
  • newValue - 新的 value 值

返回值:

如果 oldValue 不存在,对 key 对应对 value 执行替换,返回 key 对应的旧值,如果存在则替换,并返回旧值。

如果 KEY 不存在,则不做任何操作,返回null

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);

演示

// key 存在 且原 value 不为null
Integer lisaOldValue = map.replace("lisa", 333);
// 返回原来旧值 1
System.out.println(lisaOldValue);
// lisa的值已被替换  {lisa=333, hobo=null}
System.out.println(map);

System.out.println("___________________");

// key 存在 且原 value 为null
Integer hoboOldValue = map.replace("hobo", -1);
// 返回旧值 null
System.out.println(hoboOldValue);
// hobo的值已被替换 {lisa=333, hobo=-1}
System.out.println(map);
System.out.println("___________________");

// key 不存在
Integer adasOldValue = map.replace("adas", -1);
// null
System.out.println(adasOldValue);
// 未变 {lisa=333, hobo=-1}
System.out.println(map);

replaceAll

replaceAll() 方法将 映射集中的所有映射Value替换成给定的函数所执行的结果

语法:

map.replaceAll(Bifunction<K, V> function)

**注:**hashmap 是 HashMap 类的一个对象。

参数说明:

  • function - 函数式接口实例,生成映射对函数

返回值:

无,只会对映射集中的值做替换处理。

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);
map.put("qq", null);

演示

// replaceAll之前:{lisa=1, jone=2, selina=3, qq=null}
System.out.println("replaceAll之前:" + map);
map.replaceAll((k, v) -> v == null ? -1 : v * 100);

// replaceAll之后:{lisa=100, jone=200, selina=300, qq=-1}
System.out.println("replaceAll之后:" + map);

values

values() 方法返回映射中所有 value 组成的集合

语法:

hashmap.values()

参数说明:

返回值:

返回 Map 中所有 value 值所组成的集合

模拟数据:

Map<String, Integer> map = new LinkedHashMap<>(4);
map.put("lisa", 1);
map.put("jone", 2);
map.put("selina", 3);
map.put("qq", null);

演示

// [lisa, jone, selina, qq]
System.out.println(map.keySet());
// [1, 2, 3, null]
System.out.println(map.values());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值