JDK8中List轉(zhuǎn)換為Map

JDK1.8為集合提供了Stream流,可以快速的將List集合轉(zhuǎn)換為Map集合。

1. 數(shù)據(jù)準(zhǔn)備:

public class Test {
     //數(shù)據(jù)準(zhǔn)備 
    @Data
    public static class User {
        private Integer id;
        private Integer schoolId;
        private String userName;
        private String edu;
    }

    static private List<User> users = new ArrayList<>();

    static {
        User u1 = new User();
        u1.setId(1001);
        u1.setSchoolId(100);
        u1.setUserName("小1");
        u1.setEdu("001");

        User u2 = new User();
        u2.setId(1002);
        u2.setSchoolId(100);
        u2.setUserName("小2");
        u2.setEdu("002");

        User u3 = new User();
        u3.setId(2010);
        u3.setSchoolId(200);
        u3.setUserName("小3");
        u3.setEdu("001");

        User u4 = new User();
        u4.setId(3001);
        u4.setSchoolId(300);
        u4.setEdu("003");
        users.add(u1);
        users.add(u2);
        users.add(u3);
        users.add(u4);
    }
}

2. 使用方法:

  • 若是以User對象的id屬性作為key,User對象為value。轉(zhuǎn)換成的一個Map。
    public static void main(String[] args) {
        //將List轉(zhuǎn)換為Map
        Map<Integer, User> userMap = users.stream().collect(Collectors.toMap(User::getId,
                Function.identity()));

        System.out.println(JSON.toJSONString(userMap));

    }

效果一覽:

null:{"edu":"004","schoolId":400,"userName":"小5"},
3001:{"edu":"003","id":3001,"schoolId":300,"userName":"小4"},
1001:{"edu":"001","id":1001,"schoolId":100,"userName":"小1"},
2010:{"edu":"001","id":2010,"schoolId":200,"userName":"小3"},
1002:{"edu":"002","id":1002,"schoolId":100,"userName":"小2"}
}
  • 若是將對象的某個屬性作為key,某個屬性作為value。轉(zhuǎn)換成一個Map。
    public static void main(String[] args) {
        //將List轉(zhuǎn)換為Map
        Map<Integer, String> stringMap = users.stream().
                collect(Collectors.toMap(User::getId,
                        User::getEdu));
        System.out.println(JSON.toJSONString(stringMap));
    }

3. 存在的問題

  1. key相同的情況
    public static void main(String[] args) {
        //將List轉(zhuǎn)換為Map
        Map<String, User> userMap = users.stream().
                //User對象的edu屬性作為key,但是會存在key相同的情況
                collect(Collectors.toMap(User::getEdu,
                        Function.identity()));
        System.out.println(JSON.toJSONString(userMap));
    }

出現(xiàn)異常:重復(fù)秘鑰

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 
  1. value為null的情況
    public static void main(String[] args) {
        //將List轉(zhuǎn)換為Map
        Map<Integer, String> stringMap = users.stream().
                //User對象的edu屬性作為key,但是會存在key相同的情況
                        collect(Collectors.toMap(User::getId, User::getUserName));
        System.out.println(JSON.toJSONString(stringMap));
    }

出現(xiàn)異常:空指針異常

Exception in thread "main" java.lang.NullPointerException

4. 解決方案

JDK8的Collectors.toMap()提供了第三個參數(shù),來處理上面的問題。

  1. 當(dāng)出現(xiàn)重復(fù)的key問題時:合并value值。
    public static void main(String[] args) {
        //將List轉(zhuǎn)換為Map,解決key沖突的問題。
        Map<String, User> userMap = users.stream().
                //User對象的edu屬性作為key,但是會存在key相同的情況
                        collect(Collectors.toMap(User::getEdu,
                        //value的值
                        Function.identity(),
                        //合并兩個value值:k1是舊值,k2是新值。
                        (k1, k2) -> {
                            log.info(JSON.toJSONString(k1));
                            log.info(JSON.toJSONString(k2));
                            return k2;
                        }));
        System.out.println(userMap);
    }
  1. 當(dāng)出現(xiàn)value為null的情況:
    public static void main(String[] args) {
        //將List轉(zhuǎn)換為Map,解決key沖突的問題。
        Map<String, List<String>> collect = users.stream().
                //User對象的edu屬性作為key,但是會存在key相同的情況
                        collect(Collectors.toMap(User::getEdu,
                        //value的值,是集合的結(jié)構(gòu)
                        p -> {
                            //獲取value值
                            List<String> users = new ArrayList<>();
                            users.add(p.getUserName());
                            return users;
                        },
                        //集合合并
                        (List<String> k1, List<String> k2) -> {
                            k1.addAll(k2);
                            return k1;
                        }));
        System.out.println(collect);
    }

得到的集合:

{001=[小1, 小3, null], 002=[小2]}

5. 擴(kuò)展

  1. 轉(zhuǎn)換為TreeMap:
    public static void main(String[] args) {
        //將List轉(zhuǎn)換為Map,解決key沖突的問題。
        TreeMap<String, Integer> collect = users.stream().
                //User對象的edu屬性作為key,但是會存在key相同的情況
                        collect(Collectors.toMap(User::getEdu,
                        //value的值,是集合的結(jié)構(gòu)
                        User::getId,
                        (k1, k2) -> k1, TreeMap::new
                ));
        System.out.println(collect);
    }
  1. 對List進(jìn)行分組:
    public static void main(String[] args) {
        Map<String, List<User>> collect = users.stream().
                        collect(Collectors.groupingBy(User::getEdu));
        System.out.println(collect);
    }

若是想得到的value是某個值,可以使用mapping來進(jìn)行映射:

    public static void main(String[] args) {
        Map<String, List<String>> collect = users.stream().
                collect(Collectors.groupingBy(User::getEdu,
                        Collectors.mapping(User::getUserName, Collectors.toList())));
        System.out.println(collect);
    }

若是Map中key對應(yīng)的是一個List集合,那么可以使用group by來實現(xiàn)
推薦閱讀:JDK8對List進(jìn)行分組操作(stream的groupby)

推薦閱讀

List轉(zhuǎn)換為TreeMap

List轉(zhuǎn)換為HashMap的注意事項

Java8函數(shù)式編程(三):Collectors.groupingBy

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java集合類可用于存儲數(shù)量不等的對象,并可以實現(xiàn)常用的數(shù)據(jù)結(jié)構(gòu)如棧,隊列等,Java集合還可以用于保存具有映射關(guān)...
    小徐andorid閱讀 2,094評論 0 13
  • 集合類框架的介紹: ![Java 集合類框架](https://upload-images.jianshu.io/...
    LynnGuo閱讀 804評論 0 1
  • 在編程中,常常需要集中存放多個數(shù)據(jù)。集合類主要負(fù)責(zé)保存、盛裝其他數(shù)據(jù),因此集合類也被稱為容器類。所有的集合類都位于...
    一一一二二三閱讀 492評論 0 1
  • title: java集合框架學(xué)習(xí)總結(jié) tags:集合框架 categories:總結(jié) date: 2017-03...
    行徑行閱讀 1,829評論 0 2

友情鏈接更多精彩內(nèi)容