1. 程式人生 > 實用技巧 >Java8-List轉Map

Java8-List轉Map

vo

@Data
@AllArgsConstructor
public class DailyDataChartVo {

    /**
     * 日期
     */
    private LocalDate date;

    /**
     * 今日營收
     */
    private BigDecimal revenue;
}

Collectors.toMap()

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

  Collectors.toMap()一共有三個過載方法,前兩個引數都是Function介面,分別用來指定生成key和value的策略;第三個引數用來指定當key重複時的操作,如果未指定,當key重複時,直接丟擲異常;第四個引數用來指定生成Map的型別,預設建立的是HashMap。

  1. 兩個引數,key重複,直接丟擲異常
Map<LocalDate, DailyDataChartVo> map = list.stream()
        .collect(Collectors.toMap(DailyDataChartVo::getDate, Function.identity()));
  1. 三個引數,重複key,保留舊值
Map<LocalDate, DailyDataChartVo> map = list.stream()
        .collect(Collectors.toMap(DailyDataChartVo::getDate, Function.identity(), (c1, c2) -> c1));
  1. 四個引數,指定返回TreeMap
Map<LocalDate, DailyDataChartVo> map = list.stream()
        .collect(Collectors.toMap(DailyDataChartVo::getDate, Function.identity(), (c1, c2) -> c1, TreeMap::new));

Collectors.groupingBy()

public static <T, K> Collector<T, ?, Map<K, List<T>>>
groupingBy(Function<? super T, ? extends K> classifier) {
    return groupingBy(classifier, toList());
}
public static <T, K, A, D>
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                      Collector<? super T, A, D> downstream) {
    return groupingBy(classifier, HashMap::new, downstream);
}

  Collectors.groupingBy()也是三個過載方法,第一個引數是一個Function介面,用來指定分組的策略;第二個引數用來指定生成Map的型別,預設建立的是HashMap;第三個引數是一個收集器,指定對流中元素的收集策略。

  1. 一個引數,按日期分組
Map<LocalDate, List<DailyDataChartVo>> map = list.stream()
        .collect(Collectors.groupingBy(DailyDataChartVo::getDate));
  1. 兩個引數,可以指定流的收集策略
  • eg:按日期分組,統計每組的元素個數
Map<LocalDate, Long> map = list.stream()
        .collect(Collectors.groupingBy(DailyDataChartVo::getDate, Collectors.counting()));
  • eg:按日期分組,僅收集每組元素的金額
Map<LocalDate, List<BigDecimal>> map = list.stream()
        .collect(Collectors.groupingBy(DailyDataChartVo::getDate,
                Collectors.mapping(DailyDataChartVo::getRevenue, Collectors.toList())));
  • eg:按日期分組,彙總每組元素的金額總和
Map<LocalDate, BigDecimal> map = list.stream()
        .collect(Collectors.groupingBy(DailyDataChartVo::getDate,
                Collectors.mapping(DailyDataChartVo::getRevenue,
                        Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
  • eg:按日期分組,收集每組的第一個元素
Map<LocalDate, DailyDataChartVo> map = list.stream()
                .collect(Collectors.groupingBy(DailyDataChartVo::getDate,
                        Collectors.collectingAndThen(Collectors.toList(), c -> c.get(0))));
  1. 三個引數,指定返回LinkedHashMap
LinkedHashMap<LocalDate, List<DailyDataChartVo>> map = list.stream()
                .collect(Collectors.groupingBy(DailyDataChartVo::getDate, LinkedHashMap::new, Collectors.toList()));