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)

将两个流拼接在一起。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关文章
|
4天前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
160 100
|
4天前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
152 101
|
4天前
|
并行计算 Java 大数据
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
|
6天前
|
安全 Java API
使用 Java 构建强大的 REST API 的四个基本技巧
本文结合探险领域案例,分享Java构建REST API的四大核心策略:统一资源命名、版本控制与自动化文档、安全防护及标准化异常处理,助力开发者打造易用、可维护、安全可靠的稳健API服务。
51 2
|
Java
Java8中stream流处理数据21个小案例(学习使用)
Java8中stream流处理数据21个小案例(学习使用)
151 0
|
SQL 存储 前端开发
【Java技术指南】「Java8技术盲区」在奔向Java13的同时,也让我们仔细研究一下Stream的学习认知!
【Java技术指南】「Java8技术盲区」在奔向Java13的同时,也让我们仔细研究一下Stream的学习认知!
217 0
【Java技术指南】「Java8技术盲区」在奔向Java13的同时,也让我们仔细研究一下Stream的学习认知!
|
Java 程序员 API
Java 8 Stream API学习总结
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
1109 0
|
Java API 安全
JAVA8--Stream学习
Stream是什么 怎么使用Stream Stream的建立 Stream中的元素操作 Stream聚合操作 Stream结果处理 Stream分组操作 Stream注意事项 Stream是什么 书上说Stream是对JAVA中对集合处理的抽象,在我看来Stream更像是对java集合的一次扩展,因为Stream中的API都是我们对集合操作中可能遇
1870 0
|
8天前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
45 0

热门文章

最新文章