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

使用stream的Collectors.toMap()方法常見的問題及解決

 更新時(shí)間:2023年03月06日 09:14:53   作者:Rookie_cc  
這篇文章主要介紹了使用stream的Collectors.toMap()方法常見的問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

使用stream的Collectors.toMap()方法常見問題

java8開始的流式編程很大程度上簡化了我們的代碼,提高了開發(fā)效率。

我們經(jīng)常會使用到stream的Collectors.toMap()來將List轉(zhuǎn)換Map

在使用過程中有兩個(gè)小坑需要注意

1、java.lang.IllegalStateException: Duplicate key

2、java.lang.NullPointerException

第一個(gè)是由于在List轉(zhuǎn)Map過程中Map集合的key重復(fù)導(dǎo)致的;

第二個(gè)是由于在List轉(zhuǎn)Map過程中Map集合的value有null導(dǎo)致的(當(dāng)存在value值為空時(shí),使用Collectors.toMap()會報(bào)NPE,因?yàn)榈讓诱{(diào)用了Map的merge方法,而map方法規(guī)定了此處的vlue不能為null,從而拋出空指針異常);

解決方案

1、Collectors.toMap(dto ->key值 , dto -> dto,(v1,v2) -> v1)

在后面添加(v1,v2)->v1 指定選取第一個(gè)值 當(dāng)key值重復(fù)的時(shí)候,根據(jù)情況而定選取第一個(gè)還是第二個(gè))

2、自定義一個(gè)Map來接收,不使用Collectors.toMap()

第一種情況示例:

import com.google.common.collect.Lists;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.Data;
 
public class Test {
 
    private static List<User> userList = Lists.newArrayList();
 
    @Data
    public static class User {
        private String userCode;
        private String userName;
    }
 
    /**
     * 初始化數(shù)據(jù)
     * (這里的userCode=10002重復(fù))
     */
    public static void initData() {
        User user1 = new User();
        user1.setUserCode("10001");
        user1.setUserName("張三");
 
        User user2 = new User();
        user2.setUserCode("10002");
        user2.setUserName("李四");
 
        User user3 = new User();
        user3.setUserCode("10002");
        user3.setUserName("王五");
 
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
    }
 
    public static void main(String[] args) {
        initData();
        //反例
      //  Map<String, String> userMap = userList.stream().collect(Collectors.toMap(User::getUserCode, User::getUserName));
 
        //正例,在后面添加(u1,u2)->u1 指定選取第一個(gè)值 當(dāng)key值重復(fù)的時(shí)候,根據(jù)情況而定選取第一個(gè)還是第二個(gè)
        Map<String, String> userMap = userList.stream().collect(Collectors.toMap(User::getUserCode, User::getUserName, (u1, u2) -> u1));
 
        System.out.println(userMap);
    }
}

第二種情況示例:

import com.google.common.collect.Lists;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.Data;
 
public class Test {
 
    private static List<User> userList = Lists.newArrayList();
 
    @Data
    public static class User {
        private String userCode;
        private String userName;
    }
 
    /**
     * 初始化數(shù)據(jù)
     * (這里的userCode=10003的userName為空)
     */
    public static void initData() {
        User user1 = new User();
        user1.setUserCode("10001");
        user1.setUserName("張三");
 
        User user2 = new User();
        user2.setUserCode("10002");
        user2.setUserName("李四");
 
        User user3 = new User();
        user3.setUserCode("10003");
        user3.setUserName(null);
 
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
    }
 
    public static void main(String[] args) {
        initData();
        //反例
       // Map<String, String> userMap = userList.stream().collect(Collectors.toMap(User::getUserCode, User::getUserName));
 
        //正例 (如果對轉(zhuǎn)換后的順序有要求,這里還可以使用LinkedHashMap)
        Map<String, String> userMap = userList.stream().collect(HashMap::new, (map, user) -> map.put(user.getUserCode(), user.getUserName()), HashMap::putAll);
 
        System.out.println(userMap);
    }
 
}

Stream ToMap(Collectors.toMap) 實(shí)踐

Requirements

List TO Map

List Stream 轉(zhuǎn)換 Map時(shí)向collect()方法中傳遞Collector對象,對象由Collectors.toMap()方法返回。

如下實(shí)現(xiàn)List轉(zhuǎn)換為Map

List<GroupBrandCateBO> list = new ArrayList<>(
? ? ? Arrays.asList(
? ? ? ? ? ? ? new GroupBrandCateBO("v1", "g1", "b1"),
? ? ? ? ? ? ? new GroupBrandCateBO("v1", "g1", "b1"),
? ? ? ? ? ? ? new GroupBrandCateBO("v3", "g3", "b3")
? ? ? )
);
Map<String, String> map = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> oldVal, LinkedHashMap::new));?
System.out.println(map.getClass());
Map<String, String> map0 = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> oldVal));
System.out.println(map0.getClass());
System.out.println(map0.toString());
Map<String, String> map1 = list.stream().collect(Collectors.toMap(GroupBrandCateBO::getVersion, GroupBrandCateBO::getGroupCode));
System.out.println(map1.toString());

Console
class java.util.LinkedHashMap
class java.util.HashMap
{v1=g1, v3=g3}
Exception in thread “main” java.lang.IllegalStateException: Duplicate key g1
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)

問題分析

toMap()函數(shù)重載:

  • 未指定合并函數(shù)mergeFunction情況下,傳入throwingMerger()返回BinaryOperator對象,當(dāng)出現(xiàn)key重復(fù)時(shí),調(diào)用合并函數(shù)!
  • 未指定Supplier實(shí)例情況下,默認(rèn)生成HashMap實(shí)例。
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Function<? super T, ? extends U> valueMapper) {
? ? return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Function<? super T, ? extends U> valueMapper,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BinaryOperator<U> mergeFunction) {
? ? return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}

public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
? ? ? ? ? ? ? ? ? ? ? ? ? ? Function<? super T, ? extends U> valueMapper,
? ? ? ? ? ? ? ? ? ? ? ? ? ? BinaryOperator<U> mergeFunction,
? ? ? ? ? ? ? ? ? ? ? ? ? ? Supplier<M> mapSupplier) {
? ? BiConsumer<M, T> accumulator
? ? ? ? ? ? = (map, element) -> map.merge(keyMapper.apply(element),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? valueMapper.apply(element), mergeFunction);
? ? return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}

private static <T> BinaryOperator<T> throwingMerger() {
? ? return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}

補(bǔ)充

關(guān)于合并函數(shù)

List<GroupBrandCateBO> list = new ArrayList<>(
? ? ? ?Arrays.asList(
? ? ? ? ? ? ? ?new GroupBrandCateBO("v1", "g1", "b1"),
? ? ? ? ? ? ? ?new GroupBrandCateBO("v1", "g2", "b2"),
? ? ? ? ? ? ? ?new GroupBrandCateBO("v1", "g2", "b2"),
? ? ? ? ? ? ? ?new GroupBrandCateBO("v3", "g3", "b3")
? ? ? ?)
);
Map<String, String> map00 = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> currVal));
Map<String, String> map01 = list.stream().collect(Collectors.toMap(item -> item.getVersion(), item -> item.getGroupCode(), (oldVal, currVal) -> oldVal + currVal));
System.out.println(map00.toString());
System.out.println(map01.toString());

Console
{v1=g2, v3=g3}
{v1=g1g2g2, v3=g3}

傳入Lambda表達(dá)式將轉(zhuǎn)化為BinaryOperator<U> mergeFunction對象,合并處理value,非Key!??!

比如:

(oldVal, currVal) -> currVal) // key相同時(shí)當(dāng)前值替換原始值
(oldVal, currVal) -> oldVal + currVal //key相同時(shí)保留原始值和當(dāng)前值

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中的泛型詳解

    Java中的泛型詳解

    這篇文章主要介紹了Java中的泛型詳解,本文講解了泛型類或接口、從泛型類派生子類、偽泛型、類型通配符、通配符的上限、通配符的下限、擦除和轉(zhuǎn)換等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • java線程同步操作實(shí)例詳解

    java線程同步操作實(shí)例詳解

    這篇文章主要介紹了java線程同步操作,結(jié)合實(shí)例形式分析了Java線程同步與鎖機(jī)制相關(guān)原理、操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-09-09
  • Intellij idea使用Statistic統(tǒng)計(jì)代碼行數(shù)的方法

    Intellij idea使用Statistic統(tǒng)計(jì)代碼行數(shù)的方法

    這篇文章主要介紹了Intellij idea使用Statistic統(tǒng)計(jì)代碼行數(shù)的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Java調(diào)用pyzbar解析base64二維碼過程解析

    Java調(diào)用pyzbar解析base64二維碼過程解析

    這篇文章主要介紹了Java調(diào)用pyzbar解析base64二維碼過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 關(guān)于IDEA2020.1新建項(xiàng)目maven PKIX 報(bào)錯(cuò)問題解決方法

    關(guān)于IDEA2020.1新建項(xiàng)目maven PKIX 報(bào)錯(cuò)問題解決方法

    這篇文章主要介紹了關(guān)于IDEA2020.1新建項(xiàng)目maven PKIX 報(bào)錯(cuò)問題解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 完美解決idea無法搜索下載插件的問題

    完美解決idea無法搜索下載插件的問題

    這篇文章主要介紹了完美解決idea無法搜索下載插件的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 解析Java格式字符串的使用

    解析Java格式字符串的使用

    本文通過實(shí)例給大家介紹了java格式字符串的使用,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-02-02
  • Java泛型定義與用法實(shí)例詳解

    Java泛型定義與用法實(shí)例詳解

    這篇文章主要介紹了Java泛型定義與用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Java中泛型的概念、原理、定義、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-08-08
  • SpringMVC文件上傳中要解決的問題大匯總

    SpringMVC文件上傳中要解決的問題大匯總

    這篇文章主要介紹了SpringMVC文件上傳中要解決的問題,主要有中文文件名編碼問題,文件位置存儲問題以及文件名沖突問題等等,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • Sharding Jdbc批量操作引發(fā)fullGC解決

    Sharding Jdbc批量操作引發(fā)fullGC解決

    這篇文章主要為大家介紹了Sharding Jdbc批量操作引發(fā)fullGC解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11

最新評論