欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Map.merge()的示例

這篇文章給大家分享的是有關(guān)Map.merge()的示例的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。

創(chuàng)新互聯(lián)是一家專業(yè)提供千山企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站建設(shè)、H5高端網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為千山眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進(jìn)行中。

在JDK的API中,這樣的一個(gè)方法它是很特別的,它很新穎,它是值得我們花時(shí)間去了解的,同時(shí)也推薦你可以運(yùn)用到實(shí)際的項(xiàng)目代碼中,對(duì)你們應(yīng)該幫助很大。Map.merge())。這可能是Map中最通用的操作。但它也相當(dāng)模糊,幾乎很少人會(huì)去使用它。

背景介紹

merge() 可以解釋如下:它將新的值賦值給到key中(如果不存在)或更新具有給定值的現(xiàn)有key(UPSERT)。讓我們從最基本的例子開始:計(jì)算唯一的單詞出現(xiàn)次數(shù)。在java8之前的時(shí)候,代碼非?;靵y,實(shí)際的實(shí)現(xiàn)其實(shí)已經(jīng)失去了本質(zhì)層面的設(shè)計(jì)意義。

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);
    }
});

按照上述代碼的邏輯,假設(shè)給定一個(gè)輸入集合,輸出的結(jié)果如下;

var words = List.of("Foo", "Bar", "Foo", "Buzz", "Foo", "Buzz", "Fizz", "Fizz");
//...
{Bar=1, Fizz=2, Foo=3, Buzz=2}

改進(jìn)V1

現(xiàn)在讓我們來(lái)重構(gòu)它,主要去掉它的一些判斷邏輯;

words.forEach(word -> {
    map.putIfAbsent(word, 0);
    map.put(word, map.get(word) + 1);
});

這樣的改進(jìn),是可以滿足我們的重構(gòu)要求。putIfAbsent()的具體用法就不過(guò)多描述。putIfAbsent那一行代碼是一定需要的,否則,后面的邏輯也就會(huì)報(bào)錯(cuò)。而在下面代碼中,又出現(xiàn)了put、get這一點(diǎn)會(huì)很奇怪,讓我們?cè)倮^續(xù)的進(jìn)行改進(jìn)設(shè)計(jì)。

改進(jìn)V2

words.forEach(word -> {
    map.putIfAbsent(word, 0);
    map.computeIfPresent(word, (w, prev) -> prev + 1);
});

computeIfPresent是僅當(dāng) word中的的key存在的時(shí)候才調(diào)用給定的轉(zhuǎn)換。否則它什么都不處理。我們通過(guò)將key初始化為零來(lái)確保key存在,因此增量始終有效。這樣的實(shí)現(xiàn)是不是已經(jīng)足夠完美?未必,還有其他的思路可以減少額外的初始化。

words.forEach(word ->
        map.compute(word, (w, prev) -> prev != null ? prev + 1 : 1)
);

compute ()就像是computeIfPresent(),但無(wú)論給定key的存在與否如何都會(huì)調(diào)用它。如果key的值不存在,則prev參數(shù)為null。將簡(jiǎn)單移動(dòng)if 到隱藏在lambda中的三元表達(dá)式也遠(yuǎn)遠(yuǎn)沒有達(dá)到最佳的表現(xiàn)。在我向你展示最終版本之前,讓我們看一下稍微簡(jiǎn)化的默認(rèn)實(shí)現(xiàn)Map.merge()源碼分析。

改進(jìn)V3

merge()源碼
default V merge(K key, V value, BiFunction<V, V, V> remappingFunction) {
    V oldValue = get(key);
    V newValue = (oldValue == null) ? value :
               remappingFunction.apply(oldValue, value);
    if (newValue == null) {
        remove(key);
    } else {
        put(key, newValue);
    }
    return newValue;
}

代碼片段勝過(guò)千言萬(wàn)語(yǔ)。 閱讀源碼總是能夠發(fā)現(xiàn)新大陸,merge() 適用于兩種情況。如果給定的key不存在,它就變成了put(key, value)。但是,如果key已經(jīng)存在一些值,我們  remappingFunction 可以選擇合并的方式。這個(gè)功能是完美契機(jī)上面的場(chǎng)景:

  • 只需返回新值即可覆蓋舊值: (old, new) -> new
  • 只需返回舊值即可保留舊值: (old, new) -> old
  • 以某種方式合并兩者,例如: (old, new) -> old + new
  • 甚至刪除舊值: (old, new) -> null

如你所見,它  merge() 是非常通用的。那么,我們的問題該如何使用merge()呢?代碼如下:

words.forEach(word ->
        map.merge(word, 1, (prev, one) -> prev + one)
);

你可以按照如下思路理解:如果沒有key,那么初始化的value等于1;否則,將1添加到現(xiàn)有值。代碼中的 one 是一個(gè)常量,因?yàn)槲覀兊膱?chǎng)景中,默認(rèn)一直是加1,具體變化可以隨意切換。

場(chǎng)景

想象一下,merge()真的那么好用嗎?它的場(chǎng)景可以有什么?

舉一個(gè)例子。你有一個(gè)帳戶操作類

class Operation {
    private final String accNo;
    private final BigDecimal amount;
}

以及針對(duì)不同帳戶的一系列操作:

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"))
);

我們希望為每個(gè)帳戶計(jì)算余額(總運(yùn)營(yíng)金額)。假如不用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))
);

再進(jìn)行優(yōu)化的邏輯。

operations.forEach(op ->
        balances.merge(op.getAccNo(), op.getAmount(), BigDecimal::add)
);

當(dāng)然結(jié)果是正確的,這樣簡(jiǎn)潔的代碼心動(dòng)嗎?對(duì)于每個(gè)操作,add在給定的amount給定accNo。

{ 123 = 9.5,456 = - 100 }

ConcurrentHashMap

當(dāng)我們?cè)傺由斓紺oncurrentHashMap來(lái),當(dāng) Map.merge的出現(xiàn),和ConcurrentHashMap的結(jié)合那是非常的完美的。這樣的搭配場(chǎng)景是對(duì)于那些自動(dòng)執(zhí)行插入或者更新操作的單線程安全的邏輯。

感謝各位的閱讀!關(guān)于Map.merge()的示例就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

本文題目:Map.merge()的示例
分享路徑:http://www.aaarwkj.com/article32/pegspc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)電子商務(wù)、網(wǎng)站收錄、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
欧美国产精品久久综合| 日本精品视频一区二区三区| 麻豆黄片在线免费观看| 日韩精品有码在线视频免费观看| 日韩中文字幕综合不卡| 亚洲欧美韩国日本成人综合| 日韩精品视频播放一区| 国产成人99亚洲综合精品| 日韩在线一区二区视频观看| 全国最大成人免费视频| 日韩女同性一区二区三区| 大神厕所偷拍美女尿尿| 亚洲日本成人av在线观看| 日韩欧美在线观看一区二区| 欧美亚洲国产青草久久| 久久国产精品99亚洲| 午夜18禁毛片免费看| 亚洲男人天堂在线播放| 亚洲国产a级一区二区| 欧美日韩一区二区三区四区在线观看| 午夜精品一区二区亚洲| 免费一区二区不卡去日本| 熟女俱乐部五十路六十路 | 国产黄色片网站在线看| 亚洲精品国产av成人| 在线观看高清欧美国产视频| 国产精品女同久久久久久| 很色很污无遮挡的网色污| 中文有码人妻字幕在线| 亚洲熟妇av一区二区三区| 99久久精品人妻一区| 日本和亚洲的香蕉视频| 一区二区三区国产不卡| 中文字幕久久一区二区三区| 国产女技师口爆在线观看| 精品福利视频蜜臀91| 国产高清自拍视频免费| 日韩视频精品推荐一区二区| 亚洲午夜经典一区二区日韩 | 日本高清精品视频免费| 亚洲av成人在线观看|