Java8 Stream API 用法总结

简介: 本文主要讲述Stream API的用法。

一、背景

lambda和stream是Java8中两个重要的新特性,lambda表达式和函数式接口的引入赋予java函数式编程的能力,该特性改变了传统的通过对象或匿名类调用接口方法的方式,可以将函数作为方法入参进行传递,极大的简化了代码复杂性,提高了代码可读性。

Stream 是Java8是对集合操作的一种补充,是处理集合的关键抽象概念。从功能来看,集合讲的是数据,流侧重的是计算。流可以执行复杂的查找、过滤和映射等数据操作,功能类似于使用 SQL 数据库查询语句。通过集合提供的数据操作接口,再配合Stream API使我们能够高效的进行各种场景的数据处理,提升编程效率,下面我们来介绍Stream API 的使用方法。

 API使用方法介绍

 

1.Stream<T> filter(Predicate<? super T> predicate);

接收一个Predicate函数,对stream中的每个元素执行Predicate函数的test方法,过滤出符合条件的元素,返回一个新的流对象。

Predicate<Student> studentPredicate = x -> x.getAge().intValue() > 20;

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));

Stream<Student> filterStream = studentStream.filter(studentPredicate);

2.<R> Stream<R> map(Function<? super T, ? extends R> mapper);

接收一个Function函数,对原始流中的每个元素执行apply方法,每个原始元素生成一个新的元素类型,最终生成一个流。

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));
Function<Student,String> stringStudentFunction=x->x.getName();
Stream<String> names = studentStream.map(x->x.getName());

3.IntStream mapToInt(ToIntFunction<? super T> mapper);

接收ToIntFunction函数,对流程中的每个元素执行applyAsInt(T value)方法,生成一个int类型的元素,最终生成一个IntStream

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));
ToIntFunction<Student> studentToIntFunction= x->x.getAge();
IntStream intStream=studentStream.mapToInt(studentToIntFunction);

4.LongStream mapToLong(ToLongFunction<? super T> mapper);

IntStream mapToInt(ToIntFunction<? super T> mapper)接口类似。

5.DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);

IntStream mapToInt(ToIntFunction<? super T> mapper)接口类似。

6.<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

接收一个Function<? super T, ? extends Stream<? extends R>>对象,将原始流中的元素转换成一个流,针对每个元素生成的流重新组成一个新的流并返回。

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));
Function<Student,  Stream<String>> studentStreamFunction=x->Stream.of(x.getName());
Stream<String> stringStream=studentStream.flatMap(studentStreamFunction);

7.IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);

接收一个(Function<? super T, ? extends IntStream>对象,该函数对象将原始流中的元素类型转换成IntStream,针对每个元素生成的IntStream形成一个新的IntStream

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));
Function<Student,  IntStream> studentIntStreamFunction=x->(IntStream) Stream.of(x.getAge());
IntStream intStream1=studentStream.flatMapToInt(studentIntStreamFunction);

8.LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);

IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper)类似

9.DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper)

IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper)类似

10.Stream<T> distinct()

对原始流中的元素去重复,返回一个新流。

11.Stream<T> sorted();

对原始流中的元素进行排序。

12.Stream<T> sorted(Comparator<? super T> comparator)

接收Comparator<? super T>对象,对流中的元素按照compare(T o1, T o2)方法比较大小,返回一个排序流。

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));
Comparator<Student> comparator =(x,y)-> x.getName().compareTo(y.getName());
studentStream.sorted(comparator);

13.Stream<T> peek(Consumer<? super T> action);

接收一个Consumer<? super T>对象,对流中的每个元素执行accept(T t)方法,返回一个新的流

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));
Consumer<Student> studentConsumer = x->x.setName("prefix"+x.getName());
studentStream.peek(studentConsumer);

14.Stream<T> limit(long maxSize);

返回一个长度不超过maxSize的新流。

15.Stream<T> skip(long n);

跳过n个元素,生成一个新流,配合Stream<T> limit(long maxSize)可以实现分页操作。

16.void forEach(Consumer<? super T> action);

接收一个Consumer<? super T>,对流中的元素执行accept(T t)操作,这是一个终端操作。

17.void forEachOrdered(Consumer<? super T> action);

功能与void forEach(Consumer<? super T> action)类似,区别在于,并行流中该方法能保持按顺序遍历并行流中的元素。

18.Object[] toArray();

返回一个Object类型的数组。

19.<A> A[] toArray(IntFunction<A[]> generator);

针对流中的每个元素,返回一个数组

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));

Student[] students = studentStream.toArray(Student[]::new);

20.T reduce(T identity, BinaryOperator<T> accumulator);

对流中的元素按照BinaryOperator<T> 提供的方法执行聚合操作,初始值是identity,返回聚合的结果。

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));

BinaryOperator<Integer> binaryOperator=( x,y)->x+y;
Integer result= studentStream.map(x->x.getAge()).reduce(0,binaryOperator);

21.Optional<T> reduce(BinaryOperator<T> accumulator);

对流中的元素按照BinaryOperator<T>提供的方法执行聚合操作,初始值默认为流中的第一个元素,返回一个Optional对象。

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));

BinaryOperator<Integer> binaryOperator=( x,y)->x+y;
Optional<Integer> optional = studentStream.map(x -> x.getAge()).reduce(binaryOperator);

22.<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

对流中的元素按照BinaryOperator<T> 提供的方法执行聚合操作,初始值是identity,使用BinaryOperator<U> 函数对象连接并行处理结果。

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));

BiFunction<Integer,Integer,Integer> biFunction=(x,y)->x+y;
BinaryOperator<Integer> integerBinaryOperator= (x,y)->x+y;
Integer result1 = studentStream.map(x -> x.getAge()).reduce(0,biFunction,integerBinaryOperator);

23.<R> R collect(Supplier<R> supplier,
             BiConsumer<R, ? super T> accumulator,
             BiConsumer<R, R> combiner);

使用Supplier<R>创建一个结果容器,使用BiConsumer<R, ? super T>生成结果容器的元素,并放入结果容器中,BiConsumer<R, R>处理并行流情况下多个线程产生的容器元素合并的问题。

示例一:

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));

Supplier<Map<String,List<Student>>> supplier=()->new HashMap<String,List<Student>>();
BiConsumer<Map<String,List<Student>>,Student> biConsumer= (x,y)->{
   String key=y.getName();
   if(x.containsKey(key)){
       x.get(key).add(y);
   }else{
      x.put(key,Arrays.asList(y));
   }
};
BiConsumer<Map<String,List<Student>>, Map<String,List<Student>>> combiner=(x,y)->x.putAll(y);
studentStream.collect(supplier,biConsumer,combiner);

示例二

Supplier<StringBuilder> supplier1=()->new StringBuilder();
BiConsumer<StringBuilder,String> biConsumer1=(x,y)->x.append(y);
BiConsumer<StringBuilder,StringBuilder> combiner1=(x,y)->x.append(y);
String concat = stringStream.collect(supplier1,biConsumer1,combiner1).toString();

24.<R, A> R collect(Collector<? super T, A, R> collector);

使用收集器Collector<? super T, A, R>对流中的元素执行可变规约操作,收集器封装了函数(Supplier, BiConsumer, BiConsumer),java sdk提供了Collector类,改类实现了常用收集器,具体请参考Collector类源码。

Stream<Student> studentStream = Stream.of(new Student("黎明", 24, 1), new Student("黄昏", 19, 2));

Function<Student, String> studentStringFunction = x -> x.getName();
Map<String, List<Student>> map = studentStream.collect(Collectors.groupingBy(studentStringFunction));

25.Optional<T> min(Comparator<? super T> comparator);

返回流中最小的元素。

Comparator<Student> comparator1=(x,y)->x.getAge().compareTo(y.getAge());
studentStream.min(comparator1);

26.Optional<T> max(Comparator<? super T> comparator);

返回流中最大的元素。

27.long count();

返回流中元素个数。

28.boolean anyMatch(Predicate<? super T> predicate);

流中元素是否有满足Predicate<? super T>函数的元素,有返回true

29.boolean allMatch(Predicate<? super T> predicate);

流中所有元素是否都满足Predicate<? super T>函数,是返回true

30.boolean noneMatch(Predicate<? super T> predicate);

流中所有元素是否都不满足Predicate<? super T>函数,是返回true

31.Optional<T> findFirst();

返回流中第一个元素

32.Optional<T> findAny();

返回流中一个元素。

33.static<T> Stream<T> of(T t)

返回包含一个T类型元素的流对象。

34.static<T> Stream<T> of(T... values)

返回包含多个T类型元素的流对象。

35.static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

将两个流拼接在一起。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关文章
|
6月前
|
Java 测试技术 API
Java Stream API:被低估的性能陷阱与优化技巧
Java Stream API:被低估的性能陷阱与优化技巧
487 114
|
7月前
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
|
6月前
|
Java API
深入理解Java Stream API:告别繁琐循环
深入理解Java Stream API:告别繁琐循环
327 104
|
7月前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
357 100
|
7月前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
366 101
|
7月前
|
并行计算 Java 大数据
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
385 101
|
8月前
|
存储 Java API
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
434 188
|
6月前
|
Java API
详细解释一下Stream API中的sorted操作
详细解释一下Stream API中的sorted操作
416 1
|
7月前
|
存储 数据可视化 Java
Java Stream API 的强大功能
Java Stream API 是 Java 8 引入的重要特性,它改变了集合数据的处理方式。通过声明式语法,开发者可以更简洁地进行过滤、映射、聚合等操作。Stream API 支持惰性求值和并行处理,提升了代码效率和可读性,是现代 Java 开发不可或缺的工具。
143 0
Java Stream API 的强大功能
|
8月前
|
存储 NoSQL Java
Java Stream API:集合操作与并行处理
Stream API 是 Java 8 提供的集合处理工具,通过声明式编程简化数据操作。它支持链式调用、延迟执行和并行处理,能够高效实现过滤、转换、聚合等操作,提升代码可读性和性能。