/** 官方的解释
* A function that creates and returns a new mutable result container.
*
* @return a function which returns a new, mutable result container
*/Supplier<A> supplier();
/** 官方的解释
* A function that folds a value into a mutable result container.
*
* @return a function which folds a value into a mutable result container
*/BiConsumer<A, T> accumulator();
/**
* Perform the final transformation from the intermediate accumulation type
* {@code A} to the final result type {@code R}.
*
* <p>If the characteristic {@code IDENTITY_TRANSFORM} is
* set, this function may be presumed to be an identity transform with an
* unchecked cast from {@code A} to {@code R}.
*
* @return a function which transforms the intermediate result to the final
* result
*/Function<A, R> finisher();
/**
* A function that accepts two partial results and merges them. The
* combiner function may fold state from one argument into the other and
* return that, or may return a new result container.
*
* @return a function which combines two partial results into a combined
* result
*/BinaryOperator<A> combiner();
/**
* Simple implementation class for {@code Collector}.
*
* @param <T> the type of elements to be collected
* @param <R> the type of the result
*/staticclassCollectorImpl<T, A, R> implementsCollector<T, A, R> {
// 一系列的成员函数privatefinal Supplier<A> supplier;
privatefinal BiConsumer<A, T> accumulator;
privatefinal BinaryOperator<A> combiner;
privatefinal Function<A, R> finisher;
privatefinal 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);
}
@Overridepublic BiConsumer<A, T> accumulator(){
return accumulator;
}
@Overridepublic Supplier<A> supplier(){
return supplier;
}
@Overridepublic BinaryOperator<A> combiner(){
return combiner;
}
@Overridepublic Function<A, R> finisher(){
return finisher;
}
@Overridepublic Set<Characteristics> characteristics(){
return characteristics;
}
}
1.toList源码
/**
* Returns a {@code Collector} that accumulates the input elements into a
* new {@code List}. There are no guarantees on the type, mutability,
* serializability, or thread-safety of the {@code List} returned; if more
* control over the returned {@code List} is required, use {@link #toCollection(Supplier)}.
*
* @param <T> the type of the input elements
* @return a {@code Collector} which collects all the input elements into a
* {@code List}, in encounter order
*/publicstatic <T>
Collector<T, ?, List<T>> toList() {
returnnew CollectorImpl<>((Supplier<List<T>>) ArrayList::new,
//创建一个ArrayList类型的Supplier收集器
List::add,// 使用list的add函数将流中的数据添加到空结果容器中
(left, right) -> { left.addAll(right); return left; },
// lambda 表达式,将右边的list添加到左边的list中,这就是相当于一个combiner函数
CH_ID);// 表示收集器的行为参数
}
/**
* Returns a {@code Collector} that accumulates the input elements into a
* new {@code Set}. There are no guarantees on the type, mutability,
* serializability, or thread-safety of the {@code Set} returned; if more
* control over the returned {@code Set} is required, use
* {@link #toCollection(Supplier)}.
*
* <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
* Collector.
*
* @param <T> the type of the input elements
* @return a {@code Collector} which collects all the input elements into a
* {@code Set}
*/publicstatic <T>
Collector<T, ?, Set<T>> toSet() {
returnnew CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
(left, right) -> { left.addAll(right); return left; },
CH_UNORDERED_ID);
}
2. 字符拼接joining源码
①.无分隔符
/**
* Returns a {@code Collector} that concatenates the input elements into a
* {@code String}, in encounter order.
*
* @return a {@code Collector} that concatenates the input elements into a
* {@code String}, in encounter order
*
* CharSequence:这个是字符串序列接口
* joining的源码可得,实现字符串拼接是使用 StringBuilder实现的,
*/publicstatic Collector<CharSequence, ?, String> joining() {
returnnew CollectorImpl<CharSequence, StringBuilder, String>(
// 创建StringBuilder的结果容器// StringBuilder::append:拼接函数(累加器部分)
StringBuilder::new, StringBuilder::append,
// 联合成一个值,combiner部分
(r1, r2) -> { r1.append(r2); return r1; },
// 最后结果的转换
StringBuilder::toString, CH_NOID);
}
static List<User> list = Arrays.asList(
new User("y杨鑫", 50, 5455552),
new User("张三", 18, 66666),
new User("李四", 23, 77777),
new User("王五", 30, 99999),
new User("赵柳", 8, 11111),
new User("王八蛋", 99, 23233)
);
publicstaticvoidmain(String[] args){
String collect = list.stream().map(User::getUsername)
.collect(joining());
System.out.println("collect: " + collect);
}
////////////////////////////////////////输出/////////////////////////
collect: y杨鑫张三李四王五赵柳王八蛋
②.带分割符的
/**
* Returns a {@code Collector} that concatenates the input elements,
* separated by the specified delimiter, in encounter order.
* 返回一个带分割符的拼接串
* @param delimiter the delimiter to be used between each element
* @return A {@code Collector} which concatenates CharSequence elements,
* separated by the specified delimiter, in encounter order
* 将分割符传给了joining三参数的重载函数
*/publicstatic Collector<CharSequence, ?, String> joining(CharSequence delimiter){
return joining(delimiter, "", "");
}
/**
* Returns a {@code Collector} that concatenates the input elements,
* separated by the specified delimiter, with the specified prefix and
* suffix, in encounter order.
*
* @param delimiter the delimiter to be used between each element
* @param prefix the sequence of characters to be used at the beginning
* of the joined result
* @param suffix the sequence of characters to be used at the end
* of the joined result
* @return A {@code Collector} which concatenates CharSequence elements,
* separated by the specified delimiter, in encounter order
*
* 在这个函数中,使用了一个叫StringJoiner的类,这个是java8的封装类,主要的功能是
* 按照 分割符delimiter,字符串开始 prefix,字符串结尾suffix,进行字符串的拼接
*/publicstatic Collector<CharSequence, ?, String> joining(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix) {
returnnew CollectorImpl<>(
// 创建一个Supplier结果容器
() -> new StringJoiner(delimiter, prefix, suffix),
// 字符串的添加相当于 accumulator累加器部分;merge是联合将两个数值整合成一个,相当于combiner部分
StringJoiner::add, StringJoiner::merge,
// toString做最后的结果转换
StringJoiner::toString, CH_NOID);
}
publicfinalclassStringJoiner{
/**
* prefix:表示字符串拼接的前缀
* suffix:表示字符串拼接的结尾
* delimiter: 表示分割符
* */privatefinal String prefix;
privatefinal String delimiter;
privatefinal String suffix;
/*
* StringBuilder的值。构造器从prefix开始添加元素,delimiter分割,但是没有
* 结尾符suffix,那么我们每次会更容易的去拼接字符串
*/private StringBuilder value;
/*
* 默认情况,由prefix和suffix拼接的字符串,在返回值的时候使用toString转换。
* 当没有元素添加的时候,那么这个为空,这很有可能被用户去覆盖一些其他值,包括空串
*/private String emptyValue;
/**
* 构造器只有delimiter分隔符,prefix和suffix将默认为空串,
*/publicStringJoiner(CharSequence delimiter){
this(delimiter, "", "");
}
/**
* 三参数的构造器
*/publicStringJoiner(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix){
Objects.requireNonNull(prefix, "The prefix must not be null");
Objects.requireNonNull(delimiter, "The delimiter must not be null");
Objects.requireNonNull(suffix, "The suffix must not be null");
// make defensive copies of argumentsthis.prefix = prefix.toString();
this.delimiter = delimiter.toString();
this.suffix = suffix.toString();
this.emptyValue = this.prefix + this.suffix;
}
/**
* 设置空值
*/public StringJoiner setEmptyValue(CharSequence emptyValue){
this.emptyValue = Objects.requireNonNull(emptyValue,
"The empty value must not be null").toString();
returnthis;
}
/**
*
* 重写的toString,字符串将是prefix开始,suffix结尾,除非没有添加任何元素,那
* 么就返回空值
*/@Overridepublic String toString(){
if (value == null) {
return emptyValue;
} else {
if (suffix.equals("")) {
return value.toString();
} else {
int initialLength = value.length();
String result = value.append(suffix).toString();
// reset value to pre-append initialLength
value.setLength(initialLength);
return result;
}
}
}
/**
* 添加一个拼接的串
*
* @param newElement The element to add
* @return a reference to this {@code StringJoiner}
*/public StringJoiner add(CharSequence newElement){
prepareBuilder().append(newElement);
returnthis;
}
/**
* 将拼接的字串合并
*/public StringJoiner merge(StringJoiner other){
Objects.requireNonNull(other);
if (other.value != null) {
finalint length = other.value.length();
// lock the length so that we can seize the data to be appended// before initiate copying to avoid interference, especially when// merge 'this'
StringBuilder builder = prepareBuilder();
builder.append(other.value, other.prefix.length(), length);
}
returnthis;
}
private StringBuilder prepareBuilder(){
if (value != null) {
value.append(delimiter);
} else {
value = new StringBuilder().append(prefix);
}
return value;
}
/**
* 返回长度
*/publicintlength(){
// Remember that we never actually append the suffix unless we return// the full (present) value or some sub-string or length of it, so that// we can add on more if we need to.return (value != null ? value.length() + suffix.length() :
emptyValue.length());
}
}
测试
StringJoiner joiner = new StringJoiner(",", "[", "]");
for (YxUser x : list) {
joiner.add(x.getUsername());
}
joiner.merge(joiner);
// 如果没有merge将输出:joiner: [yanxgin,12,yan34xgin,56,78,90,666]/**
使用joiner.merge(joiner),将输出joiner: [yanxgin,12,yan34xgin,56,78,90,666,yanxgin,12,yan34xgin,56,78,90,666],使用merge将另外一个的StringJoiner合并进来,所以在这儿,他将已经又合并了一次
*/
System.out.println("joiner: " + joiner);
/**
* Adapts a {@code Collector} accepting elements of type {@code U} to one
* accepting elements of type {@code T} by applying a mapping function to
* each input element before accumulation.
*
* 在输入元素的累加前,使用mapping函数将一个接受U类型({@code U})的收集器调
* 整为接受T类型({@code T})的收集器。**感觉翻译不太对。
*
* @apiNote
* {@code mapping()} mapping适用于多层次的筛选,
* 例如,Person实体类集合中,计算出每个城市的姓名、
* <pre>{@code
* Map<City, Set<String>> lastNamesByCity
* = people.stream().collect(groupingBy(Person::getCity,
* mapping(Person::getLastName, toSet())));
* }</pre>
*
* @param <T> 输入元素的类型。
* @param <U> 接受元素的类型
* @param <A> 收集器的中间累加器的类型
* @param <R> 收集器的结果类型
* @param 应用于输入元素的函数
* @param downstream 收集器接受一个mapper的值
* @return a collector which applies the mapping function to the input
* elements and provides the mapped results to the downstream collector
*/publicstatic <T, U, A, R>
Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
returnnew CollectorImpl<>(downstream.supplier(),
(r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
downstream.combiner(), downstream.finisher(),
downstream.characteristics());
}