java8分组求和

3,288 阅读2分钟

求和

int sum = list.stream().mapToInt(PowerQuery::getSize).sum();
Integer collect1 = list.stream().collect(Collectors.summingInt(PowerQuery::getSize));
BigDecimal decimal = list.stream().map(PowerQuery::getNum).reduce(BigDecimal.ZERO, BigDecimal::add);

int double long 分组求和

Map<String, Integer> collect = list.stream().collect(Collectors.groupingBy(PowerQuery::getType, Collectors.summingInt(PowerQuery::getUserType)));

BigDecimal分组求和

创建CustomCollectors工具类

public final class CustomCollectors {
  private static final Set<Characteristics> CH_NOID = Collections.emptySet();

  private CustomCollectors() {}


  @SuppressWarnings("unchecked")
  private static <I, R> Function<I, R> castingIdentity() {
    return i -> (R) i;
  }

  /**
   * Simple implementation class for {@code Collector}.
   *
   * @param <T> the type of elements to be collected
   * @param <R> the type of the result
   */
  @SuppressWarnings("hiding")
  static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
    private final Supplier<A> supplier;
    private final BiConsumer<A, T> accumulator;
    private final BinaryOperator<A> combiner;
    private final Function<A, R> finisher;
    private final Set<Characteristics> characteristics;

    CollectorImpl(Supplier<A> supplier,
        BiConsumer<A, T> accumulator,
        BinaryOperator<A> combiner,
        Function<A,R> finisher,
        Set<Characteristics> characteristics) {
      this.supplier = supplier;
      this.accumulator = accumulator;
      this.combiner = combiner;
      this.finisher = finisher;
      this.characteristics = characteristics;
    }

    CollectorImpl(Supplier<A> supplier,
        BiConsumer<A, T> accumulator,
        BinaryOperator<A> combiner,
        Set<Characteristics> characteristics) {
      this(supplier, accumulator, combiner, castingIdentity(), characteristics);
    }

    @Override
    public BiConsumer<A, T> accumulator() {
      return accumulator;
    }

    @Override
    public Supplier<A> supplier() {
      return supplier;
    }

    @Override
    public BinaryOperator<A> combiner() {
      return combiner;
    }

    @Override
    public Function<A, R> finisher() {
      return finisher;
    }

    @Override
    public Set<Characteristics> characteristics() {
      return characteristics;
    }
  }

  //求和方法
  public static <T> Collector<T, ?, BigDecimal> summingBigDecimal(ToBigDecimalFunction<? super T> mapper) {
    return new CollectorImpl<>(
        () -> new BigDecimal[]{new BigDecimal(0)},
        (a, t) -> { a[0] = a[0].add(mapper.applyAsBigDecimal(t), MathContext.DECIMAL128); },
        (a, b) -> { a[0] = a[0].add(b[0], MathContext.DECIMAL128) ; return a; },
        a -> a[0], CH_NOID);
  }


  //求最大,这里的最小MIN值,作为初始条件判断值,如果某些数据范围超过百亿以后,可以根据需求换成Long.MIN_VALUE或者Double.MIN_VALUE
  public static <T> Collector<T, ?, BigDecimal> maxBy(ToBigDecimalFunction<? super T> mapper) {
    return new CollectorImpl<>(
        () -> new BigDecimal[]{new BigDecimal(Integer.MIN_VALUE)},
        (a, t) -> { a[0] = a[0].max(mapper.applyAsBigDecimal(t)); },
        (a, b) -> { a[0] = a[0].max(b[0]) ; return a; },
        a -> a[0], CH_NOID);
  }

  //求最小,这里的最大MAX值,作为初始条件判断值,如果某些数据范围超过百亿以后,可以根据需求换成Long.MAX_VALUE或者Double.MAX_VALUE
  public static <T> Collector<T, ?, BigDecimal> minBy(ToBigDecimalFunction<? super T> mapper) {
    return new CollectorImpl<>(
        () -> new BigDecimal[]{new BigDecimal(Integer.MAX_VALUE)},
        (a, t) -> { a[0] = a[0].min(mapper.applyAsBigDecimal(t)); },
        (a, b) -> { a[0] = a[0].min(b[0]) ; return a; },
        a -> a[0], CH_NOID);
  }

  /**
   * 返回一个平均值
   * @param newScale 保留小数位数
   * @param roundingMode 小数处理方式
   *     #ROUND_UP 进1
   *     #ROUND_DOWN 退1
   *     #ROUND_CEILING  进1截取:正数则ROUND_UP,负数则ROUND_DOWN
   *     #ROUND_FLOOR  退1截取:正数则ROUND_DOWN,负数则ROUND_UP
   *     #ROUND_HALF_UP >=0.5进1
   *     #ROUND_HALF_DOWN >0.5进1
   *     #ROUND_HALF_EVEN
   *     #ROUND_UNNECESSARY
   */
  //求平均,并且保留小数
  public static <T> Collector<T, ?, BigDecimal> averagingBigDecimal(ToBigDecimalFunction<? super T> mapper, int newScale, int roundingMode) {
    return new CollectorImpl<>(
        () -> new BigDecimal[]{new BigDecimal(0),new BigDecimal(0)},
        (a, t) -> { a[0] = a[0].add(mapper.applyAsBigDecimal(t)); a[1] = a[1].add(BigDecimal.ONE); },
        (a, b) -> { a[0] = a[0].add(b[0]) ; return a; },
        a -> a[0].divide(a[1], MathContext.DECIMAL128).setScale(newScale,roundingMode), CH_NOID);
  }
}
@FunctionalInterface
public interface ToBigDecimalFunction<T> {
  BigDecimal applyAsBigDecimal(T value);
}

分组求和

Map<String, BigDecimal> collect = list.stream().collect(Collectors.groupingBy(PowerQuery::getType, CustomCollectors.summingBigDecimal(PowerQuery::getUserType)));

分组空指针处理(key为null)

Map<Optional<String>, List<Record>> map = data.stream().collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getName())));
for (Entry<Optional<String>, List<Record>> entry : map.entrySet()) {
String name = entry.getKey().orElse("");
}