样例代码
实现相同id的用户账户余额累加,常规做法及merge方法代码如下
git地址
private static List<UserAccount> initDatas(){
List<UserAccount> userAccountList = new ArrayList<UserAccount>();
String ua1Id = UUID.randomUUID().toString();
String ua2Id = UUID.randomUUID().toString();
String ua3Id = UUID.randomUUID().toString();
userAccountList.add(UserAccount.builder().userId(ua1Id).userName("张三").money(100l).build());
userAccountList.add(UserAccount.builder().userId(ua1Id).userName("张三").money(200l).build());
userAccountList.add(UserAccount.builder().userId(ua1Id).userName("张三").money(300l).build());
userAccountList.add(UserAccount.builder().userId(ua2Id).userName("李四").money(100l).build());
userAccountList.add(UserAccount.builder().userId(ua2Id).userName("李四").money(100l).build());
userAccountList.add(UserAccount.builder().userId(ua3Id).userName("王五").money(300l).build());
userAccountList.add(UserAccount.builder().userId(ua3Id).userName("王五").money(100l).build());
return userAccountList;
}
// 常规方法
private static void sumAccountMoney(List<UserAccount> userAccountList){
Map<String, Long> resultMap = new HashMap<String, Long>();
userAccountList.stream().forEach(item -> {
if (resultMap.containsKey(item.getUserId())){
resultMap.put(item.getUserId(), resultMap.get(item.getUserId()) + item.getMoney());
}else{
resultMap.put(item.getUserId(), item.getMoney());
}
});
resultMap.entrySet().stream().forEach(item -> System.err.println(item.getKey() + " = " + item.getValue()));
}
// merge方法
private static void sumAccountMoneyMerge(List<UserAccount> userAccountList){
Map<String, Long> resultMap = new HashMap<String, Long>();
userAccountList.stream().forEach(item -> resultMap.merge(item.getUserId(), item.getMoney(), Long::sum));
resultMap.entrySet().stream().forEach(item -> System.err.println(item.getKey() + " = " + item.getValue()));
}
public static void main(String[] args) {
List<UserAccount> userAccountList = initDatas();
sumAccountMoney(userAccountList);
sumAccountMoneyMerge(userAccountList);
}
源码分析
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;
}
该方法接收三个参数,一个 key 值,一个 value,一个 remappingFunction ,如果给定的key不存在,它就变成了 put(key, value) 。但是,如果 key 已经存在一些值,我们 remappingFunction 可以选择合并的方式,然后将合并得到的 newValue 赋值给原先的 key