Map的merge方法(java8)


參考原文 :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 }
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM