參考原文 :https://www.jianshu.com/p/292f4e346b5d
背景介紹
merge()
可以解釋如下:它將新的值賦值給到key中(如果不存在)或更新具有給定值的現有key(UPSERT)。讓我們從最基本的例子開始:計算唯一的單詞出現次數。在java8之前的時候,代碼非常混亂,實際的實現其實已經失去了本質層面的設計意義。
var map = new HashMap<String, Integer>(); words.forEach(word -> { var prev = map.get(word); if (prev == null) { map.put(word, 1); } else { map.put(word, prev + 1); } });
按照上述代碼的邏輯,假設給定一個輸入集合,輸出的結果如下;
var words = List.of("Foo", "Bar", "Foo", "Buzz", "Foo", "Buzz", "Fizz", "Fizz"); //... {Bar=1, Fizz=2, Foo=3, Buzz=2}
場景:
例子:舉一個例子。你有一個帳戶操作類
class Operation { private final String accNo; private final BigDecimal amount; }
以及針對不同帳戶的一系列操作:
operations = List.of( new Operation("123", new BigDecimal("10")), new Operation("456", new BigDecimal("1200")), new Operation("123", new BigDecimal("-4")), new Operation("123", new BigDecimal("8")), new Operation("456", new BigDecimal("800")), new Operation("456", new BigDecimal("-1500")), new Operation("123", new BigDecimal("2")), new Operation("123", new BigDecimal("-6.5")), new Operation("456", new BigDecimal("-600")) );
我們希望為每個帳戶計算余額(總運營金額)。假如不用merge()
,就變得非常麻煩了:
Map balances = new HashMap<String, BigDecimal>(); operations.forEach(op -> { var key = op.getAccNo(); balances.putIfAbsent(key, BigDecimal.ZERO); balances.computeIfPresent(key, (accNo, prev) -> prev.add(op.getAmount())); });
使用merge
之后的代碼
operations.forEach(op -> balances.merge(op.getAccNo(), op.getAmount(), (soFar, amount) -> soFar.add(amount)) );
再進行優化的邏輯。
operations.forEach(op ->
balances.merge(op.getAccNo(), op.getAmount(), BigDecimal::add)
);
當然結果是正確的,這樣簡潔的代碼心動嗎?對於每個操作,add
在給定的amount
給定accNo
。
{ 123 = 9.5,456 = - 100 }