- merge
java8中Map类添加了merge、compute、computeIfAbsent、computeIfPresent的缺省方法,下面给出的源码都是Map类中的,Map的实现类在实现这些方法上会有不同
::方法解释::
* If the specified key is not already associated with a value or is
* associated with null, associates it with the given non-null value.
* Otherwise, replaces the associated value with the results of the given
* remapping function, or removes if the result is {@code null}. This
* method may be of use when combining multiple mapped values for a key.
// 如果一个指定的key其关联的值是空或者该key不存在,将会给他一个非空的值,除此之外,用所给的BiFunction方法的结果来替换关联的值,如果方法计算结果是null就删除该key
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;
}
①、②判断BiFunction以及默认值是否为空
③获取指定key的值赋予oldValue
④判断oldValue是否为空,如果是空newValue = 默认值,不为空newValue = BiFunction.apply(oldValue,value)
⑤判断newValue是否为空,为空就直接删除key,不为空更新key-value
::如何使用::
arrayList.forEach(a -> map.merge(a,1,(prev,one)->prev+one));
用处:循环遍历arrayList,使用map存储arrayList中值出现的次数,(prev,one)->prev+one 该函数的作用是,当有指定的key时用旧值加1作为新值更新key
// 用户账号操作类
public class Operation {
private String name;
private BigDecimal bigDecimal;
public Operation(String name, BigDecimal bigDecimal) {
this.name = name;
this.bigDecimal = bigDecimal;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getBigDecimal() {
return bigDecimal;
}
public void setBigDecimal(BigDecimal bigDecimal) {
this.bigDecimal = bigDecimal;
}
}
public class MapMergeTest {
public static void main(String[] args) {
List<Operation> operations = Arrays.asList(new Operation("123",new BigDecimal("10")),new Operation("123",new BigDecimal("-20")));
HashMap<String, BigDecimal> stringBigDecimalHashMap = new HashMap<>();
operations.forEach(operation -> stringBigDecimalHashMap.merge(operation.getName(),operation.getBigDecimal(),BigDecimal::add));
}
}
用户账号操作类是用来记录用户们每次操作的用户名和操作账户数值
最后stringBigDecimalHashMap用来保存每个用户以及其账户最终数值,用BigDecimal::add方法引用来替换之前的lamdba表达式
- compute
::方法解释::
* Attempts to compute a mapping for the specified key and its current
* mapped value (or {@code null} if there is no current mapping).
// 试着去指定一个值给给定的key
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);// 注意这里的apply中的第一个参数是对应的key,第二个参数是取出的默认值
if (newValue == null) {②如果计算出的新值是null,就保证将key删除
// 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 {③非null就设置该key为newValue,不管其是否存在
// add or replace old mapping
put(key, newValue);
return newValue;
}
}
::如何使用::
package com.example.eurekaserverdemo;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
/**
*
*/
public class MapMergeTest {
public static void main(String[] args) {
HashMap<String, Integer> stringIntegerHashMap = new HashMap<>();
stringIntegerHashMap.put("1",1);
stringIntegerHashMap.put("2",2);
stringIntegerHashMap.put("3",3);
stringIntegerHashMap.compute("1", (k,v)->v+1);①返回取出的旧值加一再设置给key
stringIntegerHashMap.compute("4",(k,v)->{
if (map.containsKey(k)) return v+1;②判断是否包含当前key,如果包含就返回oldValue+1
return 4;③如果没有key就设置一个默认值
});
System.out.println(stringIntegerHashMap.get("1"));
System.out.println(stringIntegerHashMap.get("4"));
}
}
compute方法可以做到和merge方法类似的事情,给map中不存在的key设置一个默认值,存在的key使用BiFunction来进行操作,但是compute方法没有merge方法在这方面好扩展因为它没办法指定BiFunction中的全部参数
compute优点是初始化数据的时候可以处理快一些,不论是否存在都给定一个初始值
- computeIfAbsent
::方法解释::
见名知意,该方法compute方法只用于key不存在的时候,如果key存在直接返回值
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {①注意这里传入的是一个Function,只有一个参数值,这点与compute不同
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {②判断该key不存在才执行
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {③使用传入的key值作为参数来执行传入的lambda
put(key, newValue);
return newValue;
}
}
return v;
}
- computeIfPresent
::方法解释::
该方法compute方法只用于key存在的时候,如果key不存在返回null
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {①传入两个参数
Objects.requireNonNull(remappingFunction);
V oldValue;
if ((oldValue = get(key)) != null) {②如果存在key就设置newValue
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null) {
put(key, newValue);
return newValue;
} else {
remove(key);
return null;
}
} else {
return null;
}
}