少言少语 少言少语

静以修身,俭以养德

目录
Java8 中 List 转 Map(Collectors.toMap)
/  

Java8 中 List 转 Map(Collectors.toMap)

20200208184707.jpg

使用 Java8 特性

userList.stream().collect(Collectors.toMap(User::getId, User::getName));

当然,如果希望得到 Map 的 value 为对象本身时,可以这样写:

userList.stream().collect(Collectors.toMap(User::getId, t -> t));

关于 Collectors.toMap 方法

Collectors.toMap 有三个重载方法:

image.png

image.png

image.png

toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);

toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
        BinaryOperator<U> mergeFunction);

toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
        BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);

参数含义分别是:

  1. keyMapper:Key 的映射函数
  2. valueMapper:Value 的映射函数
  3. mergeFunction:当 Key 冲突时,调用的合并方法
  4. mapSupplier:Map 构造器,在需要返回特定的 Map 时使用
    如果 List 中 userId 有相同的,使用上面的写法会抛异常:
List<User> userList = Lists.newArrayList(
        new User().setId("A").setName("张三"),
        new User().setId("A").setName("李四"), // Key 相同 
        new User().setId("C").setName("王五")
);
userList.stream().collect(Collectors.toMap(User::getId, User::getName));

异常

java.lang.IllegalStateException: Duplicate key A

这时就需要调用第二个重载方法,传入合并函数,如:

userList.stream().collect(Collectors.toMap(User::getId, User::getName, (n1, n2) -> n1 + n2));

输出结果:

A-> 张三李四 
C-> 王五

第四个参数(mapSupplier)用于自定义返回 Map 类型,比如我们希望返回的 Map 是根据 Key 排序的,可以使用如下写法:

List<User> userList = Lists.newArrayList(
        new User().setId("B").setName("张三"),
        new User().setId("A").setName("李四"),
        new User().setId("C").setName("王五")
);
userList.stream().collect(
    Collectors.toMap(User::getId, User::getName, (n1, n2) -> n1, TreeMap::new)
);

输出结果:

A-> 李四
B-> 张三
C-> 王五

Collectors 类的静态工厂方法

方法返回类型作用
toListList< T >把流中所有项目收集到一个 List
toSetSet< T >把流中所有项目收集到一个 Set,删除重复项
toCollectionCollection< T >把流中所有项目收集到给定的供应源创建的集合menuStream.collect(toCollection(), ArrayList::new)
countingLong计算流中元素的个数
sumIntInteger对流中项目的一个整数属性求和
averagingIntDouble计算流中项目 Integer 属性的平均值
summarizingIntIntSummaryStatistics收集关于流中项目 Integer 属性的统计值,例如最大、最小、 总和与平均值
joiningString连接对流中每个项目调用 toString 方法所生成的字符串collect(joining(", "))
maxByOptional< T >一个包裹了流中按照给定比较器选出的最大元素的 Optional, 或如果流为空则为 Optional.empty()
minByOptional< T >一个包裹了流中按照给定比较器选出的最小元素的 Optional, 或如果流为空则为 Optional.empty()
reducing归约操作产生的类型从一个作为累加器的初始值开始,利用 BinaryOperator 与流 中的元素逐个结合,从而将流归约为单个值累加int totalCalories = menuStream.collect(reducing(0, Dish::getCalories, Integer::sum));
collectingAndThen转换函数返回的类型包裹另一个收集器,对其结果应用转换函数int howManyDishes = menuStream.collect(collectingAndThen(toList(), List::size))
groupingByMap< K,List< T > >根据项目的一个属性的值对流中的项目作问组,并将属性值作 为结果 Map 的键
partitioningByMap< Boolean , List< T >>根据对流中每个项目应用谓词的结果来对项目进行分区

标题:Java8 中 List 转 Map(Collectors.toMap)
作者:JssDream
地址:https://www.hjava.cn/articles/2021/11/05/1636096023056.html