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)

将两个流拼接在一起。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

目录
打赏
0
0
0
0
5
分享
相关文章
|
17天前
|
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
44 11
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
Java爬虫获取微店快递费用item_fee API接口数据实现
本文介绍如何使用Java开发爬虫程序,通过微店API接口获取商品快递费用(item_fee)数据。主要内容包括:微店API接口的使用方法、Java爬虫技术背景、需求分析和技术选型。具体实现步骤为:发送HTTP请求获取数据、解析JSON格式的响应并提取快递费用信息,最后将结果存储到本地文件中。文中还提供了完整的代码示例,并提醒开发者注意授权令牌、接口频率限制及数据合法性等问题。
Java爬虫获取微店店铺所有商品API接口设计与实现
本文介绍如何使用Java设计并实现一个爬虫程序,以获取微店店铺的所有商品信息。通过HttpClient发送HTTP请求,Jsoup解析HTML页面,提取商品名称、价格、图片链接等数据,并将其存储到本地文件或数据库中。文中详细描述了爬虫的设计思路、代码实现及注意事项,包括反爬虫机制、数据合法性和性能优化。此方法可帮助商家了解竞争对手,为消费者提供更全面的商品比较。
如何在Java爬虫中设置动态延迟以避免API限制
如何在Java爬虫中设置动态延迟以避免API限制
菜鸟之路Day06一一Java常用API
《菜鸟之路Day06——Java常用API》由blue编写,发布于2025年1月24日。本文详细介绍了Java中常用的API,包括JDK7的时间类(Date、SimpleDateFormat、Calendar)和JDK8新增的时间API(ZoneId、Instant、DateTimeFormatter等),以及包装类的使用。通过多个实例练习,如时间计算、字符串转整数、十进制转二进制等,帮助读者巩固所学内容,提升编程技能。文章强调了理论与实践结合的重要性,鼓励读者多做练习以提高学习效率。
94 28
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
237 5
API对于程序员的多元用法:从基础到实战
API(应用程序编程接口)是现代软件开发中不可或缺的工具,充当不同系统间沟通的桥梁。通过API,程序员可以轻松获取外部数据、扩展应用功能、实现微服务间的通信等,极大提升开发效率和应用功能性。常见的API类型包括Web API、本地API和第三方API。使用API,开发者能快速集成复杂功能(如支付、物流跟踪),并确保数据安全与管理。掌握API的开发、维护及安全管理技巧,对构建高效、稳定的应用至关重要。随着数字化进程加速,API的重要性将不断提升。
62 1
利用 Java 代码获取淘宝关键字 API 接口
在数字化商业时代,精准把握市场动态与消费者需求是企业成功的关键。淘宝作为中国最大的电商平台之一,其海量数据中蕴含丰富的商业洞察。本文介绍如何通过Java代码高效、合规地获取淘宝关键字API接口数据,帮助商家优化产品布局、制定营销策略。主要内容包括: 1. **淘宝关键字API的价值**:洞察用户需求、优化产品标题与详情、制定营销策略。 2. **获取API接口的步骤**:注册账号、申请权限、搭建Java开发环境、编写调用代码、解析响应数据。 3. **注意事项**:遵守法律法规与平台规则,处理API调用限制。 通过这些步骤,商家可以在激烈的市场竞争中脱颖而出。
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。

热门文章

最新文章