java8特性:Collectors.groupingBy进行分组、排序等操作 (二)
2017-11-21 13:53
387 查看
参考博文
Stream类的函数
可以对数据集进行简单的分组统计。函数参数为接口Collector,其实现在final class Collectors的内部静态类CollectorImpl。Collector接口代码如下:
[b]1. Collectors.summingInt(XXX)[/b]
summingInt源码:
参数ToIntFunction类源码
返回值类所继承的接口Collector
Collectors.CollectorImpl,静态内部类
TODO放一段求平均数和求和的函数代码,完全看不懂底层实现
Stream类的函数
<R, A> R collect(Collector<? super T, A, R> collector);
可以对数据集进行简单的分组统计。函数参数为接口Collector,其实现在final class Collectors的内部静态类CollectorImpl。Collector接口代码如下:
public interface Collector<T, A, R> { Supplier<A> supplier(); BiConsumer<A, T> accumulator(); BinaryOperator<A> combiner(); Function<A, R> finisher(); Set<Characteristics> characteristics(); public static<T, R> Collector<T, R, R> of(Supplier<R> supplier, BiConsumer<R, T> accumulator, BinaryOperator<R> combiner, Characteristics... characteristics) { Objects.requireNonNull(supplier); Objects.requireNonNull(accumulator); Objects.requireNonNull(combiner); Objects.requireNonNull(characteristics); Set<Characteristics> cs = (characteristics.length == 0) ? Collectors.CH_ID : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH, characteristics)); return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs); } public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Function<A, R> finisher, Characteristics... characteristics) { Objects.requireNonNull(supplier); Objects.requireNonNull(accumulator); Objects.requireNonNull(combiner); Objects.requireNonNull(finisher); Objects.requireNonNull(characteristics); Set<Characteristics> cs = Collectors.CH_NOID; if (characteristics.length > 0) { cs = EnumSet.noneOf(Characteristics.class); Collections.addAll(cs, characteristics); cs = Collections.unmodifiableSet(cs); } return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs); } enum Characteristics { CONCURRENT, UNORDERED, IDENTITY_FINISH } }
Collectors
Collectors中静态内部类实现了Collector接口,并且提供了诸如求最大值、最小值、平均值及求和等函数,可以搭配groupingBy(XXX)使用对数据集进行分组,相关函数及使用示例如下:[b]1. Collectors.summingInt(XXX)[/b]
summingInt源码:
/** * 静态函数 * 返回一个Collector接口,其可用于产生输入元素‘int型和’的函数 * * @param <T> 输入元素类型 * @param mapper 函数,抽出需要汇总值得属性 * @return Collector ,用于产生'驱动属性'的和 */ public static <T> Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper) { return new Collectors.CollectorImpl<>( () -> new int[1],//Supplier<A> === T get(); (a, t) -> { a[0] += mapper.applyAsInt(t); },//BiConsumer<A, T> === void accept(T t, U u) (a, b) -> { a[0] += b[0]; return a; },// BinaryOperator<A> === R apply(T t, U u) a -> a[0], // Function<A,R> === R apply(T t); CH_NOID);// Set<Characteristics> == int size(); }
参数ToIntFunction类源码
@FunctionalInterface public interface ToIntFunction<T> { /** * Applies this function to the given argument. * * @param value 函数参数 */ int applyAsInt(T value); }
返回值类所继承的接口Collector
/* * 包含 * 1.返回值为函数类接口的抽象方法; * 2.of方法返回其对象实例; * 3.枚举类,包含 * CONCURRENT,UNORDERED,IDENTITY_FINISH三个元素 */ public interface Collector<T, A, R> { Supplier<A> supplier(); BiConsumer<A, T> accumulator(); BinaryOperator<A> combiner(); Function<A, R> finisher(); Set<Characteristics> characteristics(); /* 参数同其方法返回值类型 * 用给的三个函数类接口实例初始化Collector接口继承类Collectors.CollectorImpl实例,并返回 */ public static<T, R> Collector<T, R, R> of(Supplier<R> supplier, BiConsumer<R, T> accumulator, BinaryOperator<R> combiner, Characteristics... characteristics) { Objects.requireNonNull(supplier);//保证函数类接口不为null,否则抛运行时异常 Objects.requireNonNull(accumulator);//同上 Objects.requireNonNull(combiner);//同上 Objects.requireNonNull(characteristics);//同上 Set<Characteristics> cs = (characteristics.length == 0) ? Collectors.CH_ID : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH, characteristics)); return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs); } /* * 用给的三个函数类接口实例初始化Collector接口继承类Collectors.CollectorImpl实例,并返回 */ public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Function<A, R> finisher, Characteristics... characteristics) { Objects.requireNonNull(supplier); Objects.requireNonNull(accumulator); Objects.requireNonNull(combiner); Objects.requireNonNull(finisher); Objects.requireNonNull(characteristics); Set<Characteristics> cs = Collectors.CH_NOID; if (characteristics.length > 0) { cs = EnumSet.noneOf(Characteristics.class); Collections.addAll(cs, characteristics); cs = Collections.unmodifiableSet(cs); } return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs); } enum Characteristics { CONCURRENT, UNORDERED, IDENTITY_FINISH } }
Collectors.CollectorImpl,静态内部类
/** * Simple implementation class for {@code Collector}. * 1.包含几个final变量,类型同继承接口Collector构造器参数,也同其抽象方法返回值; * 2.两个构造器,实现方式与Collector类似; * 3.重载的父类方法,用其变量赋值; */ 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; } }
TODO放一段求平均数和求和的函数代码,完全看不懂底层实现
/** *求平均数 */ public static <T> Collector<T, ?, Double> averagingInt(ToIntFunction<? super T> mapper) { return new Collectors.CollectorImpl<>( () -> new long[2], (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; }, (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID); } /** *求和 */ public static <T> Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper) { return new Collectors.CollectorImpl<>( () -> new int[1], (a, t) -> { a[0] += mapper.applyAsInt(t); }, (a, b) -> { a[0] += b[0]; return a; }, a -> a[0], CH_NOID); }
相关文章推荐
- java8特性:Collectors.groupingBy进行分组、排序等操作
- Java8 stream 之groupingBy() 分组排序
- 【Python基础】之对字典进行排序操作(sort by the values of dict)
- 分组 根据某一列进行排序,根据shopid分组,用createTime排序,返回row_number()序号 select no =row_number() over (partition by shopId order by createTime desc), * from Goods_info
- SQL进行排序、分组、统计的10个新技巧(个人总结)-------Mondify By LiFuyun
- MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能.
- R 对分组的数据进行排序
- 使用ORDER BY & CHARINDEX 进行自定义排序
- es进行聚合操作时提示Fielddata is disabled on text fields by default
- SQL进行排序、分组、统计的10个新技巧
- LINQ之路14:LINQ Operators之排序和分组(Ordering and Grouping)
- java8学习之groupingBy源码分析
- Java 8 Stream Collectors groupingBy 示例
- spark对分组后value值进行排序(JAVA)
- spark对分组后value值进行排序(JAVA)
- Java表格仿mysql实现基本操作(连接,分组排序,统计等)
- 对vector等STL标准容器进行排序操作
- dataframe进行常用统计、分组统计平均绝对偏差等操作函数。
- 对vector等STL标准容器进行排序操作(转!)
- MYSQL-实现ORACLE- row_number() over(partition by ) 分组排序功能优化