自定义实现Collector,和对Characteristics的实验
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import static java.util.stream.Collector.Characteristics.*;
/**
* input Set output Map<String, String>
* eg、
* input : ["hello","world","hello world"]
* output : [{hello, hello}, {world, world}, {hello world, hello world}]
*/
public class MySetCollector2<T> implements Collector<T, Set<T>, Map<T, T>> {
@Override
public Supplier<Set<T>> supplier() {
System.out.println("supplier is invoked!");
return TreeSet<T>::new;
}
@Override
public BiConsumer<Set<T>, T> accumulator() {
System.out.println("accumulator is invoked!");
return (set, item) -> {
// 打出当前执行的线程的名称
System.out.println("accumulator " + Thread.currentThread().getName());
set.add(item);
};
}
@Override
public BinaryOperator<Set<T>> combiner() {
System.out.println("combiner is invoked!");
return (set1, set2) -> {
System.out.println("set1: " + set1);
System.out.println("set2: " + set2);
set1.addAll(set2);
return set1;
};
}
@Override
public Function<Set<T>, Map<T, T>> finisher() {
System.out.println("finisher is invoked!");
return set -> {
Map<T,T> map = new TreeMap<>();
set.forEach(item-> map.put(item,item));
return map;
};
}
@Override
public Set<Characteristics> characteristics() {
System.out.println("supplier is invoked!");
return Collections.unmodifiableSet(EnumSet.of(UNORDERED,CONCURRENT));
}
public static void main(String[] args) {
List<String> list = Arrays.asList("hello","world","hello","1","das","v","ads","ads","adsf","adf");
for (int i = 0; i < 1; i++) {
Set<String> set = new HashSet<>(list);
Map<String, String> map = list.parallelStream().collect(new MySetCollector2<>());
System.out.println(map);
}
}
}
/**
* Characteristics indicating properties of a {@code Collector}, which can
* be used to optimize reduction implementations.
*/
enum Characteristics {
/**
* Indicates that this collector is <em>concurrent</em>, meaning that
* the result container can support the accumulator function being
* called concurrently with the same result container from multiple
* threads.
*
* <p>If a {@code CONCURRENT} collector is not also {@code UNORDERED},
* then it should only be evaluated concurrently if applied to an
* unordered data source.
*/
// 指定这个后中间结果只有一个
CONCURRENT,
/**
* Indicates that the collection operation does not commit to preserving
* the encounter order of input elements. (This might be true if the
* result container has no intrinsic order, such as a {@link Set}.)
*/
// 无序的
UNORDERED,
/**
* Indicates that the finisher function is the identity function and
* can be elided. If set, it must be the case that an unchecked cast
* from A to R will succeed.
*/
// 中间结果和返回结果一致时才可以调用
IDENTITY_FINISH
}