最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java8?Collectors.toMap()?的兩種用法

 更新時(shí)間:2025年09月28日 10:21:46   作者:不愿放下技術(shù)的小趙  
Collectors.toMap():JDK8?中提供,用于將Stream流轉(zhuǎn)換為?Map,本文給大家介紹Java8?Collectors.toMap()?的兩種用法,感興趣的朋友一起看看吧

一、簡(jiǎn)單介紹

Collectors.toMap(): JDK8 中提供,用于將 Stream 流轉(zhuǎn)換為 Map。

用法1:根據(jù)某一屬性,對(duì)對(duì)象的實(shí)例或?qū)傩宰鲇成?/h3>

例如:使用 Stream 想要將集合的某一屬性(例如手機(jī)號(hào))作為 key,對(duì)象本身作為 value,這樣我們?cè)诟鶕?jù)屬性獲取實(shí)例或?qū)嵗钠渌麑傩詴r(shí)就可以省去遍歷每個(gè)對(duì)象的時(shí)間。

// 獲取 手機(jī)號(hào)-UserInfo 映射
Map<String, UserInfo> phoneNumberMap = list.stream().collect(Collectors.toMap(UserInfo::getPhoneNumber(), Function.identity());

用法2:根據(jù)某一屬性,對(duì)對(duì)象集合進(jìn)行去重

原始 JDK8 實(shí)現(xiàn)根據(jù)某一屬性去重:

// 查詢數(shù)據(jù)
List<UserInfo> list = userInfoMapper.getList();
// 根據(jù) 姓名 去重
list = list.stream().filter(o -> o.getName() != null).collect(
                Collectors.collectingAndThen(Collectors.toCollection(
                    () -> new TreeSet<>(Comparator.comparing(UserInfo::getName))), ArrayList<Aoo>::new));

通過(guò) Collectors.toMap() 實(shí)現(xiàn)根據(jù)某一屬性去重:

// 查詢數(shù)據(jù)
List<UserInfo> list = userInfoMapper.getList();
// 根據(jù) 姓名 去重
Map<String, UserInfo> collect = list.stream()
    .collect(Collectors.toMap(UserInfo::getName, o -> o, (v1, v2) -> v1));
list = new ArrayList<>(collect.values());

二、Duplicate key 異常

1)異常重現(xiàn):

    public static void main(String[] args) {
        List<User> list = Arrays.asList(
                new User("張三", 15),
                new User("張三", 16));
        // 獲取 姓名-年齡 映射
        Map<String, Integer> nameMap = list.stream().collect(Collectors.toMap(User::getName, User::getAge));
        System.out.println(nameMap);
    }
    private static class User {
        private String name;
        private Integer age;
        public User(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public Integer getAge() {
            return age;
        }
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

2)異常截圖:

3)異常說(shuō)明:

? Collectors.toMap() 在 key 重復(fù)的時(shí)候,是需要指定處理操作的。默認(rèn)并不會(huì)像 HashMap 一樣直接對(duì)原值進(jìn)行覆蓋。當(dāng)出現(xiàn) key 重復(fù)但沒(méi)有指定操作時(shí),就會(huì)拋出一個(gè) IllegalStateException 非法聲明異常。

4)異常處理:

? 我們只需要增加第3個(gè)參數(shù),指定當(dāng) key 重復(fù)時(shí)需要進(jìn)行的操作即可:

// 獲取 姓名-年齡 映射
// 第3個(gè)參數(shù)會(huì)執(zhí)行 Map.merge() 操作,(v1, v2) -> v1 表示重復(fù)時(shí)拋棄后面的值
Map<String, Integer> nameMap = list.stream()
    .collect(Collectors.toMap(User::getName, User::getAge, (v1, v2) -> v1));

? 運(yùn)行程序,輸出結(jié)果如下:

三、Collectors.toMap() 導(dǎo)致的空指針異常

1)異常重現(xiàn):

    public static void main(String[] args) {
        List<User> list = Arrays.asList(
                new User("張三", 15),
                new User("李四", null));
        // 獲取 姓名-年齡 映射
        Map<String, Integer> nameMap = list.stream()
            .collect(Collectors.toMap(User::getName, User::getAge, (v1, v2) -> v1));
        System.out.println(nameMap);
    }
    private static class User {
        private String name;
        private Integer age;
        public User(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public Integer getAge() {
            return age;
        }
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

2)異常截圖:

3)異常說(shuō)明:

? 導(dǎo)致空指針是因?yàn)?Collectors.toMap() 底層會(huì)調(diào)用 HashMap.merge() 方法,在執(zhí)行 merge() 方法的時(shí)候會(huì)對(duì) value 進(jìn)行非空判斷,從而拋出異常:

4)異常處理:

方法一:替換 null 為一個(gè)默認(rèn)值,比如 -1

// 獲取 姓名-年齡 映射
Map<String, Integer> nameMap = list.stream()
    .collect(Collectors.toMap(User::getName, o -> Optional.ofNullable(o.getAge()).orElse(-1), (v1, v2) -> v1));

運(yùn)行程序,輸出結(jié)果如下:

方法二:調(diào)用 collect() 方法實(shí)現(xiàn)

public static void main(String[] args) {
    List<User> list = Arrays.asList(
        new User("張三", 15),
        new User("張三", 16),
        new User("李四", null));
    Map<String, Integer> nameMap = list.stream()
        .collect(HashMap::new, (m, o) -> m.put(o.getName(), userInfo.getAge()), HashMap::putAll);
    System.out.println(nameMap);
}

運(yùn)行程序,輸出結(jié)果如下:

四、總結(jié)

? 綜合以上兩種異常的出現(xiàn)情況和處理方法,考慮到代碼的可讀性,最終推薦通過(guò)如下方式使用 Collectors.toMap()

// 獲取 姓名-年齡 映射
Map<String, Integer> nameMap = list.stream()
    .collect(Collectors.toMap(User::getName, o -> Optional.ofNullable(o.getAge()).orElse(-1), (v1, v2) -> v1));

參考地址:

1.Java 8中Collectors.toMap空指針異常源碼分析,http://m.fzitv.net/program/294861hkb.htm

到此這篇關(guān)于Java8 Collectors.toMap() 的使用的文章就介紹到這了,更多相關(guān)java collectors.tomap()使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

永定县| 航空| 佛山市| 疏附县| 台州市| 鄂伦春自治旗| 江陵县| 特克斯县| 类乌齐县| 乌兰浩特市| 光泽县| 离岛区| 兴山县| 吉安市| 石台县| 衡水市| 望都县| 康马县| 通化县| 雷山县| 郸城县| 屏边| 宜春市| 明水县| 乐山市| 睢宁县| 昭平县| 萨嘎县| 年辖:市辖区| 浑源县| 邵武市| 金湖县| 惠水县| 弋阳县| 元阳县| 睢宁县| 昌宁县| 灵寿县| 茂名市| 视频| 临澧县|