Java 8 : Stream.collect 和 Collectors.toMap

Stream.collect :

import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Stream.collect
 */
public class Test4 {
    
    

    public static void main(String[] args) {
    
    
        System.out.println("=============test1==============");
        test1();
        System.out.println("=============test2==============");
        test2();
        System.out.println("=============test3==============");
        test3();
    }

    /**
     * Stream.collect()和Collectors.joining()一起使用
     */
    private static void test3() {
    
    
        List<String> list = Arrays.asList("Ram", "Shyam", "Shiv", "Mahesh");
        String result1 = list.stream().collect(Collectors.joining(", "));
        System.out.println("Joining Result1: " + result1);
        //Joining Result1: Ram, Shyam, Shiv, Mahesh
        //等价于
        String result2 = String.join(", ", list);
        System.out.println("Joining Result2: " + result2);
        //Joining Result2: Ram, Shyam, Shiv, Mahesh
    }

    /**
     * <R> R collect(
     * Supplier<R> supplier,
     * BiConsumer<R, ? super T> accumulator,
     * BiConsumer<R, R> combiner);
     * <p>
     * supplier:【供应者】,它创建一个新的结果容器,
     * 由累加器(accumulator)和组合器(combiner)填充,最后由collect()方法返回。
     * 在并行处理中,将多次调用Supplier函数,每次都将返回新值。
     * <p>
     * accumulator:【累加器】,它在结果中加入了额外的元素。
     * <p>
     * combiner:【组合器】,它组合了两个必须与累加器兼容的值。组合器(combiner)工作在并行处理中。
     * <p>
     * stream: 适用于避免线程安全问题、要求顺序执行、数据处理简单不耗时的任务;
     * parallelStream: 适用于不存在线程安全问题、不需要顺序性执行、数据处理比较耗时的任务;
     */
    private static void test2() {
    
    
        List<String> list = Arrays.asList("Mukesh", "Vishal", "Amar");
        String result1 = list.parallelStream().collect(
                StringBuilder::new,
                (response, element) -> response.append(" ").append(element),
                (response1, response2) -> response1.append(",").append(response2.toString())
        ).toString();
        System.out.println("Result1: " + result1);
        //Result1:  Mukesh, Vishal, Amar
        //
        String result2 = list.stream().collect(
                StringBuilder::new,
                (response, element) -> response.append(" ").append(element),
                (response1, response2) -> response1.append(",").append(response2.toString())
        ).toString();
        System.out.println("Result2: " + result2);
        //如果我们使用list.stream()则输出将不同,因为它不是并行处理,因此没有任何内容可以组合。
        //Result2:  Mukesh Vishal Amar
    }

    /**
     * Stream.collect()使用收集器(Collector)
     * <R, A> R collect(Collector<? super T, A, R> collector);
     */
    private static void test1() {
    
    
        List<Integer> list = Arrays.asList(23, 43, 12, 25);
        IntSummaryStatistics stats = list.stream().collect(
                Collectors.summarizingInt(i -> i + i)
        );
        System.out.println("Sum:" + stats.getSum());
        //Sum:206
    }

}

Collectors.toMap :

md5.txt:

application.cfg:ac081180e86fc34401bb287dbd64b7db
byd_car.kzb:b6e529c101e0e39d429c5ef8cc41cb4b
environment_main.kzb:bd36e26fe1aa424f842d22ae0adbf025
environment_textures.kzb:5a4ae53168dad59e60988c05aa7cf6c
javaIF.xml:d69fbf79729df053726926c359ea44b9
master_mycar.kzb:2a851c9ffc44e797a8e9be3765a152f
master_mycar.kzb.cfg:f3516f974e06bbd00f261ea6c6025112
master_mycar.kzb.txt:a05adb1c686f576b3653fae77d539b38
version.json:f74402f76fefba1cb5a68a16feec92d1
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Collectors.toMap
 */
public class Test3 {
    
    

    public static void main(String[] args) {
    
    
        System.out.println("======test1=======");
        test1();
        System.out.println("======test2=======");
        test2();
        System.out.println("======test3=======");
        test3();
        System.out.println("======test4=======");
        test4();
        System.out.println("======test5=======");
        test5();
        System.out.println("======test6=======");
        test6();
    }

    /**
     * 收集 Stream 流中的数据到集合中
     * //1.收集数据到list集合中
     * stream.collect(Collectors.toList())
     * //2.收集数据到set集合中
     * stream.collect(Collectors.toSet())
     * //3.收集数据到指定的集合中
     * Collectors.toCollection(Supplier<C> collectionFactory)
     * stream.collect(Collectors.joining())
     */
    private static void test6() {
    
    
        //收集流中的数据到集合中
        //1.收集流中的数据到 list

        List<String> list = Stream.of("aaa", "bbb", "ccc", "bbb")
                .collect(Collectors.toList());
        System.out.println(list);
        //[aaa, bbb, ccc, bbb]

        //2.收集流中的数据到 set
        Set<String> collect = Stream.of("aaa", "bbb", "ccc", "bbb")
                .collect(Collectors.toSet());
        System.out.println(collect);
        //[aaa, ccc, bbb]

        //3.收集流中的数据(ArrayList)(不收集到list,set等集合中,而是)收集到指定的集合中
        ArrayList<String> arrayList = Stream.of("aaa", "bbb", "ccc", "bbb")
                .collect(Collectors.toCollection(ArrayList::new));
        System.out.println(arrayList);
        //[aaa, bbb, ccc, bbb]

        //4.收集流中的数据到 HashSet
        HashSet<String> hashSet = Stream.of("aaa", "bbb", "ccc", "bbb")
                .collect(Collectors.toCollection(HashSet::new));
        System.out.println(hashSet);
        //[aaa, ccc, bbb]
    }

    /**
     * <R> R collect(
     * Supplier<R> supplier,
     * BiConsumer<R, ? super T> accumulator,
     * BiConsumer<R, R> combiner);
     */
    private static void test5() {
    
    
        String file = "md5.txt";
        try (Stream<String> stream = Files.lines(Paths.get(file))) {
    
    
            HashMap<String, String> hashMap = stream.filter(string -> !string.isEmpty())
                    .collect(new Supplier<HashMap<String, String>>() {
    
    
                                 @Override
                                 public HashMap<String, String> get() {
    
    
                                     return new HashMap<String, String>();
                                 }
                             },
                            new BiConsumer<HashMap<String, String>, String>() {
    
    
                                @Override
                                public void accept(HashMap<String, String> map, String item) {
    
    
                                    map.put(
                                            item.split(":")[0],
                                            item.split(":")[1]
                                    );
                                }
                            },
                            new BiConsumer<HashMap<String, String>, HashMap<String, String>>() {
    
    
                                @Override
                                public void accept(HashMap<String, String> map, 
                                                   HashMap<String, String> map1) {
    
    
                                    map.putAll(map1);
                                }
                            });
            //可简化为:
//            HashMap<String, String> hashMap2 = stream.filter(string -> !string.isEmpty())
//                    .collect(HashMap::new,
//                            (map, item) -> map.put(
//                                    item.split(":")[0],
//                                    item.split(":")[1]
//                            ),
//                            HashMap::putAll);
            for (Map.Entry<String, String> entry : hashMap.entrySet()) {
    
    
                System.out.println(entry.getKey() + " => " + entry.getValue());
            }

//            //也可这样实现:
//            Map<String, String> hashMap3 = stream
//                    .filter(string -> !string.isEmpty())
//                    .collect(Collectors.toMap(
//                            item -> item.split(":")[0],
//                            item -> item.split(":")[1]
//                    ));
//            for (Map.Entry<String, String> entry : hashMap3.entrySet()) {
    
    
//                System.out.println(entry.getKey() + " => " + entry.getValue());
//            }

        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("e=>" + e.getMessage());
        }
    }

    /**
     * Map中的value不能为null
     */
    private static void test4() {
    
    
        List<User> userList = new ArrayList<>();
        userList.add(new User("A", "张三"));
        userList.add(new User("D", "李四"));
        userList.add(new User("C", null));

//        //Map中的value不能为null
//        //会报错: Exception in thread "main" java.lang.NullPointerException
//        Map<String, String> map1 = userList.stream().collect(Collectors.toMap(
//                User::getId,
//                User::getName,
//                (n1, n2) -> n1,
//                TreeMap::new
//        ));
//        System.out.println(map1);

        //<R> R collect(Supplier<R> supplier,
        //                  BiConsumer<R, ? super T> accumulator,
        //                  BiConsumer<R, R> combiner);
        Map<String, String> map2 = userList.stream().collect(
                HashMap::new,
                (m, v) -> m.put(v.getId(), v.getName()),
                HashMap::putAll
        );
        System.out.println(map2);
        //{A=张三, C=null, D=李四}
    }

    /**
     * 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) {
     * 参数含义分别是:
     * keyMapper:Key 的映射函数
     * valueMapper:Value 的映射函数
     * mergeFunction:当 Key 冲突时,调用的合并方法
     * mapSupplier:Map 构造器,在需要返回特定的 Map 时使用
     * <p>
     * 【第四个参数(mapSupplier)】用于自定义返回 Map 类型,比如我们希望返回的 Map 是根据 Key 排序的,
     * 可以使用如下写法
     * <p>
     * TreeMap是一个有序的 key-value 集合,它是通过红黑树实现的,会根据其键(key)进行自然排序。
     */
    private static void test3() {
    
    
        List<User> userList = new ArrayList<>();
        userList.add(new User("C", "张三"));
        userList.add(new User("B", "李四"));
        userList.add(new User("A", "王五"));
        TreeMap<String, String> treeMap = userList.stream().collect(Collectors.toMap(
                User::getId,//map的key
                User::getName,//map的value
                (n1, n2) -> n1,//解决map的key重复问题
                TreeMap::new//特定map,这里排序
        ));
        System.out.println(treeMap);
        //{A=王五, B=李四, C=张三}
    }

    /**
     * Map中的key不能重复(可通过BinaryOperator规避)
     * <p>
     * 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) {
     * 参数含义分别是:
     * keyMapper:Key 的映射函数
     * valueMapper:Value 的映射函数
     * mergeFunction:当 Key 冲突时,调用的合并方法
     */
    private static void test2() {
    
    
        List<User> userList = new ArrayList<>();
        userList.add(new User("A", "张三"));
        userList.add(new User("A", "李四"));// Key 相同
        userList.add(new User("C", "王五"));

        //会报错:Exception in thread "main" java.lang.IllegalStateException: Duplicate key 张三
//        System.out.println(userList.stream().collect(Collectors.toMap(User::getId, User::getName)));

        //Collectors.toMap第三个参数解决
        Map<String, String> stringMap = userList.stream().collect(Collectors.toMap(
                User::getId,//map的key
                User::getName,//map的value
                (n1, n2) -> n1 + n2)//解决map的key重复问题
        );
        System.out.println(stringMap);
        //{A=张三李四, C=王五}
    }

    /**
     * public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(
     * Function<? super T, ? extends K> keyMapper,
     * Function<? super T, ? extends U> valueMapper) {
     * 参数含义分别是 :
     * keyMapper:Key 的映射函数
     * valueMapper:Value 的映射函数
     */
    private static void test1() {
    
    
        List<User> userList = new ArrayList<>();
        userList.add(new User("A", "张三"));
        userList.add(new User("B", "李四"));
        userList.add(new User("C", "王五"));

        //希望转成 Map 的格式为
        //A-> 张三
        //B-> 李四
        //C-> 王五

        //过去做法循环:
        Map<String, String> stringMap1 = new HashMap<>();
        for (User user : userList) {
    
    
            stringMap1.put(user.getId(), user.getName());
        }
        System.out.println("stringMap1=>" + stringMap1);

        //使用 Java8 特性 :
        Map<String, String> stringMap2 = userList.stream()
                .collect(Collectors.toMap(User::getId, User::getName));
        System.out.println("stringMap2=>" + stringMap2);
        //
        //当然,如果希望得到 Map 的 value 为对象本身时,可以这样写
        Map<String, User> stringUserMap1 = userList.stream()
                .collect(Collectors.toMap(User::getId, t -> t));
        System.out.println("stringUserMap1=>" + stringUserMap1);
        //或
        Map<String, User> stringUserMap2 = userList.stream()
                .collect(Collectors.toMap(User::getId, Function.identity()));
        System.out.println("stringUserMap2=>" + stringUserMap2);
        //stringMap1=>{A=张三, B=李四, C=王五}
        //stringMap2=>{A=张三, B=李四, C=王五}
        //stringUserMap1=>{A=User{id='A', name='张三'},
        // B=User{id='B', name='李四'}, C=User{id='C', name='王五'}}
        //stringUserMap2=>{A=User{id='A', name='张三'},
        // B=User{id='B', name='李四'}, C=User{id='C', name='王五'}}
    }

    static class User {
    
    
        private String id;
        private String name;

        public User(String id, String name) {
    
    
            this.id = id;
            this.name = name;
        }

        public String getId() {
    
    
            return id;
        }

        public void setId(String id) {
    
    
            this.id = id;
        }

        public String getName() {
    
    
            return name;
        }

        public void setName(String name) {
    
    
            this.name = name;
        }

        @Override
        public String toString() {
    
    
            return "User{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

}

猜你喜欢

转载自blog.csdn.net/sinat_31057219/article/details/132542339
今日推荐