首页 > Java > Java8通过Stream将List转换成Map类型

Java8通过Stream将List转换成Map类型

2024年4月12日
  1. Java提供的api接口
    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);
    }
/**
第一个参数是一个函数接口,使用输入的类型用来生成Key
*/
(Function<? super T, ? extends K> keyMapper
/**
第二个参数也是一个函数接口,使用输入的类型用来生成Value
*/
Function<? super T, ? extends U> valueMapper

举例说明

    /*
    Function.identit()是Function提供的个静态方法也可以使用lambda:e->e
    */
    @Test
    public void test01(){
     List<String> names = Arrays.asList("tom","jack","jerry");
        Map<String, Integer> collect = names.stream().collect(toMap(Function.identity(), String::length));
        System.out.println(collect);
    }

这个有一个致命的问题,很容易出现Key的冲突,这个代码就会报错,例如:

 @Test
    public void  test02(){
        List<String> names = Arrays.asList("tom","jack","jerry","tom");
        Map<String, Integer> collect = names.stream().collect(toMap(Function.identity(), String::length));
        System.out.println(collect)

     }                                   
 /*
   因为List包含两个tom,转成Map会有两个同样的Key,这个是不允许的。所以会报错:
   java.lang.IllegalStateException: Duplicate key 3
   at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
   at java.util.HashMap.merge(HashMap.java:1254)
  */

2.Java提供的另一个api

 /*
    BinaryOpera 同样是一个函数式接口(U,U) ->U
    在转map时可以让开发人员约定如何处理
 */
 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);
    }

举例说明

  /*
  保留第一个,后面的丢弃
  */
  @Test
    public void  test03(){
        List<String> names = Arrays.asList("tom","jack","jerry","tom");
        Map<String, Integer> collect = names.stream().collect(toMap(Function.identity(), String::length,(e1,e2)->e1));
        System.out.println(collect);
    }
  /*
  保留最新的,覆盖之前的
  */
    @Test
    public void  test04(){
        List<String> names = Arrays.asList("tom","jack","jerry","tom");
        Map<String, Integer> collect = names.stream().collect(toMap(Function.identity(), String::length,(e1,e2)->e2));
        System.out.println(collect);
    }
  /*
  如果全部保留,必须使用容器,Value就要是集合类型,对应Key不冲突的,容器只有一个元素
  对应Key冲突的容器会有多个元素。
  */
  @Test
    public void test05() {
        List<String> names = Arrays.asList("tom", "jack", "jerry", "tom");
        Map<String, List<Integer>> collect = names.stream().collect(toMap(Function.identity(),
                e -> {
                    List<Integer> list = new ArrayList<>();
                    list.add(e.length());
                    return list;
                },
                (e1, e2) -> {
                    e1.addAll(e2);
                    return e1;
                }
        ));
        System.out.println(collect);
    }

3.Java提供的另一个api

 /*
  Supplier<M> mapSupplier 同样时一个函数式接口,用来返回一个容器
  之前的代码都有包含一段:HashMap::new,代表toMap返回的默认时HashMap
  这个参数让开发人员可以根据实际需要替换其他的容器
 */


    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);
    }

举例说明

  @Test
    public void test06() {
        List<String> names = Arrays.asList("tom", "jack", "jerry", "tom");
        Map<String, List<Integer>> collect = names.stream().collect(toMap(Function.identity(),
                e -> {
                    List<Integer> list = new ArrayList<>();
                    list.add(e.length());
                    return list;
                },
                (e1, e2) -> {
                    e1.addAll(e2);
                    return e1;
                },
                LinkedHashMap::new
        ));
        System.out.println(collect.getClass());
        System.out.println(collect);
    }
分类: Java 标签: , ,
本文的评论功能被关闭了.