import java.util.ArrayList; import java.util.List; import java.util.Set; 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; public class MyListCollector<T> implements Collector<T, List<T>, List<T>>{ @Override public Supplier<List<T>> supplier() { return ArrayList<T>::new; } @Override public BiConsumer<List<T>, T> accumulator() { // return ArrayList<T>::add; return List::add; } @Override public BinaryOperator<List<T>> combiner() { return null; } @Override public Function<List<T>, List<T>> finisher() { return null; } @Override public Set<Characteristics> characteristics() { return null; } }
import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; 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.CONCURRENT; import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH; import static java.util.stream.Collector.Characteristics.UNORDERED; public class MySetCollector<T> implements Collector<T, Set<T>, Set<T>> { @Override public Supplier<Set<T>> supplier() { System.out.println("supplier"); return HashSet<T>::new; } // 如果return HashSet<T>::add,那么会编译报错,原因在于 // 如果这里return的是HashSet,而supplier方法返回的是TreeSet // 那么显然,中间用于累积的容器的类型二者是不一致的;就会出现问题 // 如果这里使用了Set::add,即接口类型,那么它就会兼容于supplier // 所返回的容器类型 // 总之:这里return的类型必须要与泛型的类型保持完全一致 @Override public BiConsumer<Set<T>, T> accumulator() { System.out.println("accumulator"); // return Set<T>::add; return (set, item) -> { System.out.println(item + ", " + set + ", " + Thread.currentThread().getName() ); set.add(item); }; } @Override public BinaryOperator<Set<T>> combiner() { System.out.println("combiner"); return (set1, set2) -> { set1.addAll(set2); return set1; }; } @Override public Function<Set<T>, Set<T>> finisher() { System.out.println("finisher"); return Function.identity(); // 对于IDENTITY_FINISH来说,该方法可以直接抛出异常,该方法实际上并不会被调用 // throw new UnsupportedOperationException(); } // 该方法会被调用2次,分别用于确定UNORDERED与IDENTITY_FINISH @Override public Set<Characteristics> characteristics() { System.out.println("characteristics"); return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH, CONCURRENT, UNORDERED)); } public static void main(String[] args) { List<String> list = Arrays.asList("hello", "world", "welcome", "hello", "a", "b", "c", "d", "e", "f", "g", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii"); Set<String> preSet = new HashSet<>(); preSet.addAll(list); System.out.println(preSet); Set<String> set = preSet.stream().parallel().collect(new MySetCollector<>()); System.out.println("---------------"); System.out.println(set); // System.out.println(Runtime.getRuntime().availableProcessors()); } }
import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; 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; public class MySetCollector2<T> implements Collector<T, Set<T>, Map<T, T>> { @Override public Supplier<Set<T>> supplier() { System.out.println("supplier invoked!"); // 串行流调用时,只会生成一个HashSet // 并行流调用时,每个线程都会生成一个HashSet /** * * A a1 = supplier.get(); * accumulator.accept(a1, t1); * accumulator.accept(a1, t2); * R r1 = finisher.apply(a1); // result without splitting * * A a2 = supplier.get(); * accumulator.accept(a2, t1); * A a3 = supplier.get(); * accumulator.accept(a3, t2); * R r2 = finisher.apply(combiner.apply(a2, a3)); // result with splitting */ return () -> { System.out.println("~~~~~~~~~~~~~~~~~"); return new HashSet<T>(); }; // return HashSet<T>::new; } @Override public BiConsumer<Set<T>, T> accumulator() { System.out.println("accumulator invoked!"); return (set, item) -> { System.out.println("accumulator, " + set + ", " + Thread.currentThread().getName()); set.add(item); }; } @Override public BinaryOperator<Set<T>> combiner() { System.out.println("combiner invoked!"); return (set1, set2) -> { System.out.println("combiner, " + set1 + ", " + set2); set1.addAll(set2); return set1; }; } @Override public Function<Set<T>, Map<T, T>> finisher() { System.out.println("finisher invoked!"); return set -> { System.out.println("finisher, " + set); Map<T, T> map = new TreeMap<>(); set.stream().forEach(item -> map.put(item, item)); return map; }; } @Override public Set<Characteristics> characteristics() { System.out.println("characteristics invoked!"); // return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED, Characteristics.IDENTITY_FINISH)); return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED, Characteristics.CONCURRENT)); } public static void main(String[] args) { System.out.println(Runtime.getRuntime().availableProcessors()); List<String> list = Arrays.asList("hello", "world", "welcome", "hello", "a", "b", "c", "d", "e", "f", "g"); Set<String> set = new HashSet<>(); set.addAll(list); System.out.println("set: " + set); System.out.println("----------"); //串行执行时combiner并不会得到调用,combiner只在并行流时会得到调用 // Map<String, String> map = set.stream().parallel().sequential().parallel().collect(new MySetCollector2<>()); Map<String, String> map = set.parallelStream().collect(new MySetCollector2<>()); System.out.println(map); } }
import java.util.Arrays; import java.util.Comparator; import java.util.IntSummaryStatistics; import java.util.List; import java.util.Map; import java.util.Optional; import static java.util.stream.Collectors.averagingInt; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.counting; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.maxBy; import static java.util.stream.Collectors.minBy; import static java.util.stream.Collectors.partitioningBy; import static java.util.stream.Collectors.summarizingInt; import static java.util.stream.Collectors.summingInt; import static java.util.stream.Collectors.toList; public class StreamTest1 { public static void main(String[] args) { Student student1 = new Student("zhangsan", 80); Student student2 = new Student("lisi", 90); Student student3 = new Student("wangwu", 100); Student student4 = new Student("zhaoliu", 90); Student student5 = new Student("zhaoliu", 90); List<Student> students = Arrays.asList(student1, student2, student3, student4, student5); // List<Student> students1 = students.stream().collect(toList()); // students1.forEach(System.out::println); // System.out.println("------------"); // // // System.out.println("count: " + students.stream().collect(counting())); // System.out.println("count: " + students.stream().count()); // System.out.println("------------"); // // // students.stream().collect(minBy(Comparator.comparingInt(Student::getScore))).ifPresent(System.out::println); // // students.stream().collect(maxBy(Comparator.comparingInt(Student::getScore))).ifPresent(System.out::println); // // System.out.println(students.stream().collect(averagingInt(Student::getScore))); // // System.out.println(students.stream().collect(summingInt(Student::getScore))); // // IntSummaryStatistics intSummaryStatistics = students.stream().collect(summarizingInt(Student::getScore)); // System.out.println(intSummaryStatistics); // System.out.println("------------"); // // System.out.println(students.stream().map(Student::getName).collect(joining())); // System.out.println(students.stream().map(Student::getName).collect(joining(", "))); // System.out.println(students.stream().map(Student::getName).collect(joining(", ", "<begin> ", " <end>"))); // System.out.println("------------"); // // Map<Integer, Map<String, List<Student>>> map = students.stream(). // collect(groupingBy(Student::getScore, groupingBy(Student::getName))); // System.out.println(map); // System.out.println("------------"); // // Map<Boolean, List<Student>> map2 = students.stream(). // collect(partitioningBy(student -> student.getScore() > 80)); // System.out.println(map2); // System.out.println("------------"); // // Map<Boolean, Map<Boolean, List<Student>>> map3 = students.stream(). // collect(partitioningBy(student -> student.getScore() > 80, // partitioningBy(student -> student.getScore() > 90))); // System.out.println(map3); // System.out.println("------------"); // // Map<Boolean, Long> map4 = students.stream(). // collect(partitioningBy(student -> student.getScore() > 80, counting())); // System.out.println(map4); // System.out.println("------------"); //// // Map<String, Student> map5 = students.stream(). // collect(groupingBy(Student::getName, // collectingAndThen(minBy(Comparator.comparingInt(Student::getScore)), // Optional::get))); // System.out.println(map5); } }
import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class StreamTest2 { public static void main(String[] args) { List<String> list = Arrays.asList("nihao", "hello", "world", "welcome"); // Collections.sort(list, (item1, item2) -> item1.length() - item2.length()); // Collections.sort(list, (item1, item2) -> item2.length() - item1.length()); // Collections.sort(list, Comparator.comparingInt(String::length).reversed()); //// 此处lambda参数的类型推断无法推断出item为String类型,需要显式指定;原因在于这是一个独立的参数,并不是通过list调用方法来得出的 // Collections.sort(list, Comparator.comparingInt((String item) -> item.length()).reversed()); //// 如下代码无法编译通过,因为lambda参数要求参数类型应该是String或是String的父类,而Boolean则不是 // Collections.sort(list, Comparator.comparingInt((Boolean item) -> 1).reversed()); //// Collections的sort就是调用List的sort实现的 // list.sort(Comparator.comparingInt(String::length).reversed()); //// 如下代码必须要显式声明item的类型为String // list.sort(Comparator.comparingInt((String item) -> item.length()).reversed()); // // // Collections.sort(list, Comparator.comparingInt(String::length).thenComparing(String.CASE_INSENSITIVE_ORDER)); // // // 为何下面这个thenComparing中的参数类型可以推断出来? // Collections.sort(list, Comparator.comparingInt(String::length). // thenComparing((item1, item2) -> item1.toLowerCase().compareTo(item2.toLowerCase()))); // Collections.sort(list, Comparator.comparingInt(String::length). // thenComparing(Comparator.comparing(String::toLowerCase))); // Collections.sort(list, Comparator.comparingInt(String::length). // thenComparing(Comparator.comparing(String::toLowerCase, Comparator.reverseOrder()))); //// // // welcome, world, nihao, hello // Collections.sort(list, Comparator.comparingInt(String::length).reversed(). // thenComparing(Comparator.comparing(String::toLowerCase, Comparator.reverseOrder()))); // // // welcome, world, nihao, hello, 注意:thenComparing都是根据前一个compare的结果来决定此次是否进行再次排序, // // 如果前一次排序不返回0,那么此次排序结果就直接返回之前的排序结果 Collections.sort(list, Comparator.comparingInt(String::length).reversed(). thenComparing(Comparator.comparing(String::toLowerCase, Comparator.reverseOrder())). thenComparing(Comparator.reverseOrder())); System.out.println(list); } }
public class Student { private String name; private int score; public Student(String name, int score) { this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", score=" + score + '}'; } }