/** 官方的解釋 * 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());
}
複製代碼