欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì)

 更新時(shí)間:2020年09月02日 10:19:55   作者:明明如月學(xué)長(zhǎng)  
這篇文章主要介紹了詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

 1. 介紹

本入門教程將介紹Java8中如何合并兩個(gè)map。

更具體說(shuō)來(lái),我們將研究不同的合并方案,包括Map含有重復(fù)元素的情況。

2. 初始化

我們定義兩個(gè)map實(shí)例

private static Map<String, Employee> map1 = new HashMap<>();
private static Map<String, Employee> map2 = new HashMap<>();

Employee類

public class Employee {
 
 private Long id;
 private String name;
 
 // 此處省略構(gòu)造方法, getters, setters方法
}

然后往map中存入一些數(shù)據(jù)

Employee employee1 = new Employee(1L, "Henry");
map1.put(employee1.getName(), employee1);
Employee employee2 = new Employee(22L, "Annie");
map1.put(employee2.getName(), employee2);
Employee employee3 = new Employee(8L, "John");
map1.put(employee3.getName(), employee3);
 
Employee employee4 = new Employee(2L, "George");
map2.put(employee4.getName(), employee4);
Employee employee5 = new Employee(3L, "Henry");
map2.put(employee5.getName(), employee5);

特別需要注意的是employee1 和 employee5在map中有完全相同的key(name)。

3. Map.merge()

Java8為 java.util.Map接口新增了merge()函數(shù)。

 merge()  函數(shù)的作用是: 如果給定的key之前沒(méi)設(shè)置value 或者value為null, 則將給定的value關(guān)聯(lián)到這個(gè)key上.

否則,通過(guò)給定的remaping函數(shù)計(jì)算的結(jié)果來(lái)替換其value。如果remapping函數(shù)的計(jì)算結(jié)果為null,將解除此結(jié)果。

First, let's construct a new HashMap by copying all the entries from the map1:

首先,我們通過(guò)拷貝map1中的元素來(lái)構(gòu)造一個(gè)新的HashMap

Map<String, Employee> map3 = new HashMap<>(map1);

然后引入merge函數(shù)和合并規(guī)則

map3.merge(key, value, (v1, v2) -> new Employee(v1.getId(),v2.getName())

最后對(duì)map2進(jìn)行迭代將其元素合并到map3中

map2.forEach(
 (key, value) -> map3.merge(key, value, (v1, v2) -> new Employee(v1.getId(),v2.getName())));

運(yùn)行程序并打印結(jié)果如下:

John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
Henry=Employee{id=1, name='Henry'}

最終,通過(guò)結(jié)果可以看出,實(shí)現(xiàn)了兩個(gè)map的合并,對(duì)重復(fù)的key也合并為同一個(gè)元素。

注意最后一個(gè)Employee的id來(lái)自map1而name來(lái)自map2.

原因是我們的merge函數(shù)的定義

(v1, v2) -> new Employee(v1.getId(), v2.getName())

4. Stream.concat()

Java8的Stream API 也為解決該問(wèn)題提供了較好的解決方案。

首先需要將兩個(gè)map合為一個(gè)Stream。

Stream combined = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream());

我們需要將entry sets作為參數(shù),然后利用Collectors.toMap():將結(jié)果放到新的map中。

Map<String, Employee> result = combined.collect(
 Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

該方法可以實(shí)現(xiàn)map的合并,但是有重復(fù)key會(huì)報(bào)IllegalStateException異常。

為了解決這個(gè)問(wèn)題,我們需要加入lambda表達(dá)式merger作為第三個(gè)參數(shù)

(value1, value2) -> new Employee(value2.getId(), value1.getName())

當(dāng)檢測(cè)到有重復(fù)Key時(shí)就會(huì)用到該lambda表達(dá)式。

現(xiàn)在把上面代碼組合在一起:

Map<String, Employee> result = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
 .collect(Collectors.toMap(
 Map.Entry::getKey, 
 Map.Entry::getValue,
 (value1, value2) -> new Employee(value2.getId(), value1.getName())));

最終的結(jié)果

George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}
Henry=Employee{id=3, name='Henry'}

從結(jié)果可以看出重復(fù)的key “Henry”將合并為一個(gè)新的鍵值對(duì),id取自map2,name取自map1。

5. Stream.of()

通過(guò)Stream.of()方法不需要借助其他stream就可以實(shí)現(xiàn)map的合并。

Map<String, Employee> map3 = Stream.of(map1, map2)
 .flatMap(map -> map.entrySet().stream())
 .collect(Collectors.toMap(
 Map.Entry::getKey,
 Map.Entry::getValue,
 (v1, v2) -> new Employee(v1.getId(), v2.getName())));

首先將map1和map2的元素合并為同一個(gè)流,然后再轉(zhuǎn)成map。通過(guò)使用v1的id和v2的name來(lái)解決重復(fù)key的問(wèn)題。

map3的運(yùn)行打印結(jié)果如下:

6. Simple Streaming

我們還可以借助stream的管道操作來(lái)實(shí)現(xiàn)map合并。

Map<String, Employee> map3 = map2.entrySet()
 .stream()
 .collect(Collectors.toMap(
 Map.Entry::getKey,
 Map.Entry::getValue,
 (v1, v2) -> new Employee(v1.getId(), v2.getName()),
 () -> new HashMap<>(map1)));

結(jié)果如下:

{John=Employee{id=8, name='John'},
Annie=Employee{id=22, name='Annie'},
George=Employee{id=2, name='George'},
Henry=Employee{id=1, name='Henry'}}

7. StreamEx

我們還可以使Stream API 的增強(qiáng)庫(kù)

Map<String, Employee> map3 = EntryStream.of(map1)
 .append(EntryStream.of(map2))
 .toMap((e1, e2) -> e1);

注意 (e1, e2) -> e1 表達(dá)式來(lái)處理重復(fù)key的問(wèn)題,如果沒(méi)有該表達(dá)式依然會(huì)報(bào)IllegalStateException異常。

結(jié)果:

{George=Employee{id=2, name='George'},
John=Employee{id=8, name='John'},
Annie=Employee{id=22, name='Annie'},
Henry=Employee{id=1, name='Henry'}}

8 總結(jié)

本文使用了Map.merge(), Stream API, StreamEx 庫(kù)實(shí)現(xiàn)map的合并。

英文原文地址:https://www.baeldung.com/java-merge-maps

到此這篇關(guān)于詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì)的文章就介紹到這了,更多相關(guān)Java8合并Map中元素內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java內(nèi)置GUI Frame類的使用

    Java內(nèi)置GUI Frame類的使用

    這篇文章主要介紹了Java內(nèi)置GUI Frame類的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java優(yōu)雅的關(guān)閉線程池的方法

    Java優(yōu)雅的關(guān)閉線程池的方法

    本文主要介紹了Java如何優(yōu)雅的關(guān)閉線程池,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java數(shù)組索引異常產(chǎn)生及解決方案

    Java數(shù)組索引異常產(chǎn)生及解決方案

    這篇文章主要介紹了Java數(shù)組索引異常產(chǎn)生及解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 一文搞懂Spring?Security異常處理機(jī)制

    一文搞懂Spring?Security異常處理機(jī)制

    這篇文章主要為大家詳細(xì)介紹一下Spring?Security異常處理機(jī)制,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Spring?Security有一定幫助,感興趣的可以學(xué)習(xí)一下
    2022-07-07
  • Java分頁(yè)查詢的幾種實(shí)現(xiàn)方法舉例

    Java分頁(yè)查詢的幾種實(shí)現(xiàn)方法舉例

    這篇文章主要給大家介紹了關(guān)于Java分頁(yè)查詢的幾種實(shí)現(xiàn)方法,分頁(yè)是系統(tǒng)中常用到的功能,只要涉及到查詢必定伴隨而來(lái)的就是分頁(yè),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • logback整合rabbitmq實(shí)現(xiàn)消息記錄日志的配置

    logback整合rabbitmq實(shí)現(xiàn)消息記錄日志的配置

    這篇文章主要介紹了logback整合rabbitmq實(shí)現(xiàn)消息記錄日志的配置,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-12-12
  • Java微信二次開(kāi)發(fā)(三) Java微信各類型消息封裝

    Java微信二次開(kāi)發(fā)(三) Java微信各類型消息封裝

    這篇文章主要為大家詳細(xì)介紹了Java微信二次開(kāi)發(fā)第三篇,Java微信各類型消息封裝,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java多線程的實(shí)現(xiàn)方式比較(兩種方式比較)

    Java多線程的實(shí)現(xiàn)方式比較(兩種方式比較)

    Java多線程實(shí)現(xiàn)方式有兩種,第一種是繼承Thread類,第二種是實(shí)現(xiàn)Runnable接口,兩種有很多差異,下面跟著本文一起學(xué)習(xí)吧
    2015-11-11
  • RestTemplate報(bào)錯(cuò)I/O?error?on?POST?request?for的解決辦法

    RestTemplate報(bào)錯(cuò)I/O?error?on?POST?request?for的解決辦法

    這篇文章主要給大家介紹了關(guān)于RestTemplate報(bào)錯(cuò)I/O?error?on?POST?request?for的解決辦法,文中通過(guò)代碼實(shí)例將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • Java 八道經(jīng)典面試題之鏈表題

    Java 八道經(jīng)典面試題之鏈表題

    本位主要介紹了Java面試中常常遇到的八道經(jīng)典鏈表問(wèn)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的小伙伴們可以學(xué)習(xí)一下
    2021-11-11

最新評(píng)論