java 自定义 operator_java8 自定义Collector
package com.lgx.jdk8.part02;
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;
/**
* 自定義Collector,定義一個Set收集器
*/
public class Test13MySetCollector{
public static void main(String[] args) {
List list = Arrays.asList("hello", "world", "hello", "welcome");
Set set = list.stream().collect(new MySetCollector<>());
System.out.println("set = " + set);
System.out.println("========================");
List list2 = Arrays.asList("hello", "world", "hello", "welcome", "a", "b", "c", "d");
Set set2 = new HashSet<>();
set2.addAll(list2);
System.out.println("set2 = " + set2);
//如果parallel和sequential寫多個,以最后一個為準,因為在實現中就是以一個boolean來判斷的
for (int i = 0; i < 1; i++) {//執行100次驗證并行,加這個參數CONCURRENT報錯問題
//Map map = set2.stream().collect(new MyMapCollector<>()); //串行
//Map map = set2.parallelStream().collect(new MyMapCollector<>()); //并行
Map map = set2.stream().sequential().collect(new MyMapCollector<>()); //串行
//Map map = set2.stream().parallel().collect(new MyMapCollector<>()); //并行
System.out.println("map = " + map);
}
System.out.println("可運行線程數=總cpu-被占用的cpu = " + Runtime.getRuntime().availableProcessors());
}
}
//自定義收集器,輸入時Set,輸出是Set
class MySetCollector implements Collector, Set> {
//創建一個新的容器
@Override
public Supplier> supplier() {
System.out.println("MySetCollector supplier invoked");
return HashSet::new;
}
//累加器:添加一個元素到容器
@Override
public BiConsumer, T> accumulator() {
System.out.println("MySetCollector accumulator invoked");
//return HashSet::add;//這里不能給一個具體的Set,因為supplier方法可能返回的是TreeSet,不一定是HashSet
return Set::add;
}
//把并行流多個結果合并
@Override
public BinaryOperator> combiner() {
System.out.println("MySetCollector combiner invoked");
return (set1, set2) -> {
set1.addAll(set2);
return set1;
};
}
//完成器:合并完返回最終結果
@Override
public Function, Set> finisher() {
System.out.println("MySetCollector finisher invoked");
//return t -> t;
return Function.identity();//與上面那個等價
//throw new UnsupportedOperationException();
}
//返回一個集合,標識這個集合的諸多特性
/**
* Characteristics有3個值:
* CONCURRENT:表示可以并行收集
* UNORDERED:元素不保證順序的
* IDENTITY_FINISH:表示會執行一個強制類型轉換,會調用finisher()方法
*/
@Override
public Set characteristics() {
System.out.println("MySetCollector characteristics invoked");
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED));
}
}
//自定義收集器,輸入時Set,輸出是Map
class MyMapCollector implements Collector, Map> {
//創建一個新的容器
@Override
public Supplier> supplier() {
System.out.println("MyMapCollector supplier invoked");
//return HashSet::new;
return () -> {
System.out.println("***************");//串行這里只執行一次,并行這里執行多次
return new HashSet();
};
}
//累加器:添加一個元素到容器
@Override
public BiConsumer, T> accumulator() {
System.out.println("MyMapCollector accumulator invoked");
//return Set::add;
return (set, item) -> {
System.out.println("MyMapCollector accumulator set = " + set + " " + Thread.currentThread().getName());
//報錯在于這里調用(打印)了set,和下面的代碼產生了一邊修改一邊迭代,刪掉這個打印就好了
set.add(item);
};
}
//把并行流多個結果合并
@Override
public BinaryOperator> combiner() {
System.out.println("MyMapCollector combiner invoked");
return (set1, set2) -> {
set1.addAll(set2);
System.out.println("MyMapCollector combiner set1 = " + set1 + " set2 = " + set2);
return set1;
};
}
//完成器:合并完返回最終結果
@Override
public Function, Map> finisher() {
System.out.println("MyMapCollector finisher invoked");
return set -> {
Map map = new HashMap();
set.stream().forEach(item -> map.put(item, item));
return map;
};
}
//返回一個集合,標識這個集合的諸多特性
@Override
public Set characteristics() {
System.out.println("MyMapCollector characteristics invoked");
//return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));//運行會報錯,因為這樣會執行強制類型轉換,而事實上無法將一個Set強制轉換成Map
/**
* Characteristics.CONCURRENT:
* 如果上面調用parallelStream,不管有沒有這個屬性都是并行
* 不加這個屬性,是多個線程操作多個結果容器,combiner也會調用多次
* 加了這個屬性,是多個線程操作一個結果容器,combiner也無需調用了
*/
return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));//合并方法執行多次
//return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED, Characteristics.CONCURRENT));//合并方法不會執行,多次運行該示例可能拋出異常ConcurrentModificationException
/**
* ConcurrentModificationException:并發修改異常,一個線程修改在一個集合,另一個集合在迭代這個集合,就會報出這個異常
* 不加CONCURRENT,多個容器,也就互不干擾了;加了就一個容器,就會出現這個問題
*/
}
}
總結
以上是生活随笔為你收集整理的java 自定义 operator_java8 自定义Collector的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java精确测量文本高度_Android
- 下一篇: java+pom.xml+是什么_jav