sorted(Comparator com) | 定制排序,自定义Comparator排序器 | ComparatorList<Author> authors = StreamDataInit.getAuthors();List<Author> defaultList = authors.stream().sorted().collect(Collectors.toList());defaultList.forEach(e -> System.out.println(“Id:”+ e.getId()+“, Name: “+e.getName()+“, Age:”+e.getAge()));defaultList = authors.stream().sorted(Comparator.comparing(Author::getAge).reversed()).collect(Collectors.toList());defaultList.forEach(e -> System.out.println(“Id:”+ e.getId()+“, Name: “+e.getName()+“, Age:”+e.getAge())); 多个排序 userList = userList.stream().sorted(Comparator.comparing(User::getAge).reversed().thenComparing(User::getClassNo, Comparator.reverseOrder())).collect(Collectors.toList());userList = userList.stream().sorted(Comparator.comparing(User::getAge, Comparator.reverseOrder()).thenComparing(User::getClassNo, Comparator.reverseOrder())).collect(Collectors.toList());userList = userList.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getClassNo).reversed()).collect(Collectors.toList());
总结: sorted的参数 如果只进行单个字段的升序降序排列,我们使用reversed() 或者 Comparator.reverseOrder() 都可以 如果要进行多个字段的升序降序排列,我们还是使用 Comparator.reverseOrder() 会更优雅、更好理解一些 参数形式速记 - 无参数
sorted() 这种排序相当于没有排序,他返回的是自然排序,而stream本身是无序的 Comparator.comparing(Author::getAge) Comparator.comparing(Author::getAge).reversed() Comparator.comparing(User::getAge, Comparator.reverseOrder()) Comparator.comparing(User::getAge, Comparator.reverseOrder()).thenComparing(User::getName, Comparator.reverseOrder())
4、消费peek :如同于map ,能得到流中的每一个元素。但map 接收的是一个Function 表达式,有返回值;而peek 接收的是Consumer 表达式,没有返回值。peek :如同于forEach ,peek 是中间操作,而forEach 是终端操作
Student s1 = new Student("aa", 10);Student s2 = new Student("bb", 20);List<Student> studentList = Arrays.asList(s1, s2);studentList.stream().peek(o -> o.setAge(100)).forEach(System.out::println);Student{name='aa', age=100}Student{name='bb', age=100}
三、Terminal(只有一次):通过最终(terminal)方法完成对数据集中元素的最终处理。
1、 匹配、聚合操作名称 | 含义 | 参数类型 |
---|
allMatch | 接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false | Predicate | noneMatch | 接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false | Predicate | anyMatch | 接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false | Predicate | findFirst | 返回流中第一个元素 | 无 | findAny | 返回流中的任意元素 | 无 | count | 返回流中元素的总个数 | 无 | max | 返回流中元素最大值 | Comparator | min | 返回流中元素最小值 | Comparator |
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);boolean allMatch = list.stream().allMatch(e -> e > 10); boolean noneMatch = list.stream().noneMatch(e -> e > 10); boolean anyMatch = list.stream().anyMatch(e -> e > 4); Integer findFirst = list.stream().findFirst().get(); Integer findAny = list.stream().findAny().get(); long count = list.stream().count(); Integer max = list.stream().max(Integer::compareTo).get(); Integer min = list.stream().min(Integer::compareTo).get();
2、 规约操作规约操作又被称作折叠操作,是通过某个连接动作将所有元素汇总成一个汇总结果的过程。元素求和、求最大值或最小值、求出元素总个数、将所有元素转换成一个列表或集合,都属于规约操作。_Stream_类库有两个通用的规约操作reduce()和collect(),也有一些为简化书写而设计的专用规约操作,比如sum()、max()、min()、count()等。 List<Author> authors = StreamDataInit.getAuthors(); Integer sum = authors.stream() .distinct() .map(author -> author.getAge()) .reduce(0, (result, element) -> result + element); System.out.println(sum); Integer reduce1 = authors.stream() .map(author -> author.getAge()) .reduce(Integer.MIN_VALUE, (result, element) -> result < element " />: result); System.out.println(reduce1); Integer reduce2 = authors.stream() .map(author -> author.getAge()) .reduce(Integer.MAX_VALUE, (result, element) -> result > element ? element : result); System.out.println(reduce2); Optional<Integer> reduce = authors.stream() .map(author -> author.getAge()) .reduce(new BinaryOperator<Integer>() { @Override public Integer apply(Integer result, Integer element) { return result > element ? element : result; } }); reduce.ifPresent(age -> System.out.println(age)); List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4); Optional<Integer> sum1 = list.stream().reduce((x, y) -> x + y); Optional<Integer> sum2 = list.stream().reduce(Integer::sum); Integer sum3 = list.stream().reduce(0, Integer::sum); System.out.println("list求和:" + sum1.get() + "," + sum2.get() + "," + sum3); Integer sum4 = authors.stream().collect(Collectors.reducing(0, Author::getAge, (i, j) -> (i + j - 5000))); System.out.println("作家扣税薪资总和:" + sum4); Optional<Integer> sum5 = authors.stream().map(Author::getAge).reduce(Integer::sum); System.out.println("作家薪资总和:" + sum5.get()); BigDecimal sumSalary = authors.stream() .map(Author::getSalary) .reduce(BigDecimal.ZERO, BigDecimal::add); System.out.println("工资之和:"+sumSalary); Optional<Integer> product = list.stream().reduce((x, y) -> x * y); Optional<Integer> max1 = list.stream().reduce((x, y) -> x > y ? x : y); Integer max2 = list.stream().reduce(1, Integer::max); System.out.println("list求积:" + product.get()); System.out.println("list求和:" + max1.get() + "," + max2);
3、 收集操作collect :接收一个Collector 实例,将流中元素收集成另外一个数据结构。Collector 是一个接口,有以下5个抽象方法 :
名称 | 含义 |
---|
Supplier supplier() | 创建一个结果容器A | BiConsumer accumulator() | 消费型接口,第一个参数为容器A,第二个参数为流中元素T | BinaryOperator combiner() | 函数接口,该参数的作用跟上一个方法(reduce)中的combiner参数一样,将并行流中各 个子进程的运行结果(accumulator函数操作后的容器A)进行合并 | Function finisher() | 函数式接口,参数为:容器A,返回类型为:collect方法最终想要的结果R | Set characteristics() | 返回一个不可变的Set集合,用来表明该Collector的特征。有以下三个特征CONCURRENT:表示此收集器支持并发。UNORDERED:表示该收集操作不会保留流中元素原有的顺序。IDENTITY_FINISH:表示finisher参数只是标识而已,可忽略。 |
public class CollectorCustom {public static void main(String[] args) {Set<Integer> collect = Arrays.asList(1, 2, 3, 3, 4, 5, 6).stream().collect(new MyCollector<Integer>());System.out.println(collect);}public static class MyCollector<T> implements Collector<T, Set<T>, Set<T>> {@Overridepublic Supplier<Set<T>> supplier() {System.out.println("MyCollector.supplier");return HashSet::new;-->我们提供一个HashSet}@Overridepublic BiConsumer<Set<T>, T> accumulator() {System.out.println("MyCollector.accumulator");return Set::add; -->我们处理Set 和流中元素T的关系 }@Overridepublic BinaryOperator<Set<T>> combiner() {System.out.println("MyCollector.combiner");return (st1, st2) -> {st1.addAll(st2);return st1; ->如果是并发流,创建了多个容器,我们处理多个容器间的关系};}@Overridepublic Function<Set<T>, Set<T>> finisher() {System.out.println("MyCollector.finisher");return Function.identity();-> 处理 容器和最终返回的规约,我们选择都是返回Set<T>}@Overridepublic Set<Characteristics> characteristics() {System.out.println("MyCollector.characteristics");return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH, UNORDERED));--> 当我们使用了 IDENTITY_FINISH ,其实就不用再写finisher();不知道你明不明白?--> UNORDERED 不追求顺序,我们毕竟用的HashSet}}}
4、collect实战
收集 Stream 流中的数据到集合中stream.collect(Collectors.toList())stream.collect(Collectors.toSet())Collectors.toCollection(Supplier<C> collectionFactory)stream.collect(Collectors.joining())
public class CollectDataToCollection{public static void main(String[] args) {Stream<String> stream = Stream.of("aaa", "bbb", "ccc", "bbb");List<String> list = stream.collect(Collectors.toList());System.out.println(list);Set<String> collect = stream.collect(Collectors.toSet());System.out.println(collect);ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));System.out.println(arrayList);HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));System.out.println(hashSet);}}
收集 Stream 流中的数据到数组中Object[] toArray();<A> A[] toArray(IntFunction<A[]> generator);
public class CollectDataToArray{public static void main(String[] args) {Stream<String> stream = Stream.of("aaa", "bbb", "ccc", "bbb"); Object[] objects = stream.toArray();for (Object o: objects) {System.out.println("data:"+o);}String[] strings = stream.toArray(String[]::new);for(String str : strings){System.out.println("data:"+str + ",length:"+str.length());}}}
Stream流中数据聚合/分组/分区/拼接操作Collectors.maxBy();Collectors.minBy();Collectors.summingInt();/Collectors.summingDouble();/Collectors.summingLong();Collectors.averagingInt();/Collectors.averagingDouble();/Collectors.averagingLong();Collectors.counting();
聚合操作public class CollectDataToArray{public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 58, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 99),new Student("柳岩", 52, 77));Optional<Student> max = studentStream.collect(Collectors.maxBy((s1, s2) -> s1.getScore() - s2.getScore()));System.out.println("最大值:"+max.get());Optional<Student> min = studentStream.collect(Collectors.minBy((s1, s2) -> s1.getScore() - s2.getScore()));System.out.println("最小值:"+min.get());Integer ageSum = studentStream.collect(Collectors.summingInt(Student::getAge));System.out.println("年龄总和:"+ageSum);Double avgScore = studentStream.collect(Collectors.averagingInt(Student::getScore));System.out.println("分数平均值:"+avgScore);Long count = studentStream.collect(Collectors.counting());System.out.println("数量为:"+count);}}
分组操作groupingBy(Function<? super T, ? extends K> classifier)
public class CollectDataToArray{public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 52, 56),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 99),new Student("柳岩", 52, 53));Map<Integer, List<Student>> map = studentStream.collect(Collectors.groupingBy((s -> s.getAge())));map.forEach((key,value)->{System.out.println(key + "-->"+value);});Map<String, List<Student>> map = studentStream.collect(Collectors.groupingBy(s -> {if (s.getScore() >= 60) {return "及格";} else {return "不及格";}}));map.forEach((key,value)->{System.out.println(key + "-->"+value.get());});Map<Integer, Optional<Student>> reducingMap = studentStream.collect(Collectors.groupingBy(Student::getAge, Collectors.reducing(BinaryOperator.maxBy(Comparator.comparingInt(Student::getScore)))));reducingMap .forEach((key,value)->{System.out.println(key + "-->"+value);});}}
多级分组操作groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream)
public class CollectDataToArray{public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 55),new Student("柳岩", 52, 33));Map<Integer, Map<Integer, Map<String, List<Student>>>> map = studentStream.collect(Collectors.groupingBy(str -> str.getAge(), Collectors.groupingBy(str -> str.getScore(), Collectors.groupingBy((student) -> {if (student.getScore() >= 60) {return "及格";} else {return "不及格";}}))));map.forEach((key,value)->{System.out.println("年龄:" + key);value.forEach((k2,v2)->{System.out.println("\t" + v2);});});}}
分组和分区分组和分区的区别就在:分组可以有多个组。分区只会有两个区( true 和 false)
partitioningBy(Predicate<? super T> predicate)partitioningBy(Predicate<? super T> predicate, Collector<? super T, A, D> downstream)
public class CollectDataToArray{public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 55),new Student("柳岩", 52, 33));Map<Boolean, List<Student>> partitionMap = studentStream.collect(Collectors.partitioningBy(s -> s.getScore() > 60));partitionMap.forEach((key,value)->{System.out.println(key + "-->" + value);});}}
拼接操作joining()joining(CharSequence delimiter)joining(CharSequence delimiter, CharSequence prefix,CharSequence suffix)
public class CollectDataToArray{public static void main(String[] args) {Stream<Student> studentStream = Stream.of(new Student("赵丽颖", 52, 95),new Student("杨颖", 56, 88),new Student("迪丽热巴", 56, 55),new Student("柳岩", 52, 33));String joinStr1 = studentStream.map(s -> s.getName()).collect(Collectors.joining());System.out.println(joinStr1);String joinStr2 = studentStream.map(s -> s.getName()).collect(Collectors.joining(","));System.out.println(joinStr2);String joinStr3 = studentStream.map(s -> s.getName()).collect(Collectors.joining("—","^_^",">_<"));System.out.println(joinStr3);}}
|