您的位置:首页 > 编程语言 > Java开发

java8特性:Collectors.groupingBy进行分组、排序等操作 (二)

2017-11-21 13:53 387 查看
参考博文

  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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数式编程 java