/** 官方的解释 * 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());
}
复制代码