热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java8Stream流Intermediate中间操作详细解析

Stream的操作中有中间操作和终端操作,顾名思义,中间操作就是对stream流的一些操作,操作对象时stream本身,终端操作既是对流的处理结

Stream的操作中有中间操作和终端操作,顾名思义,中间操作就是对stream流的一些操作,操作对象时stream本身,终端操作既是对流的处理结果,为了直观的了解,我们看下接口定义:

public interface Stream<T> extends BaseStream<T, Stream<T>> {Stream<T> filter(Predicate<? super T> predicate);<R> Stream<R> map(Function<? super T, ? extends R> mapper);IntStream mapToInt(ToIntFunction<? super T> mapper);LongStream mapToLong(ToLongFunction<? super T> mapper);DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);Stream<T> distinct();Stream<T> sorted();Stream<T> sorted(Comparator<? super T> comparator);Stream<T> peek(Consumer<? super T> action);Stream<T> limit(long maxSize);Stream<T> skip(long n);void forEach(Consumer<? super T> action);void forEachOrdered(Consumer<? super T> action);Object[] toArray();<A> A[] toArray(IntFunction<A[]> generator);T reduce(T identity, BinaryOperator<T> accumulator);Optional<T> reduce(BinaryOperator<T> accumulator);<U> U reduce(U identity,BiFunction<U, ? super T, U>accumulator,
BinaryOperator<U> combiner);<R> R collect(Supplier<R> supplier,iConsumer<R, ? super T> accumulator,iConsumer<R, R> combiner);<R, A> R collect(Collector<? super T, A, R> collector);Optional<T> min(Comparator<? super T> comparator);Optional<T> max(Comparator<? super T> comparator);long count();boolean anyMatch(Predicate<? super T> predicate);boolean allMatch(Predicate<? super T> predicate);boolean noneMatch(Predicate<? super T> predicate);Optional<T> findFirst();Optional<T> findAny();public static<T> Builder<T> builder() {return new Streams.StreamBuilderImpl<>();}public static<T> Stream<T> empty() {return StreamSupport.stream(Spliterators.<T>emptySpliterator(), false);}public static<T> Stream<T> of(T t) {return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);}public static<T> Stream<T> of(T... values) {return Arrays.stream(values);}
}

对于返回值为** 接口本身的Stream ** 或者返回 其他对象类型的&#xff0c;返回接口类型的我们都可认为是中间操作&#xff0c;返回 其他具体类型的为终端操作。
下面我们来具体看每个方法&#xff1a;
1、filter(Predicate) 将结果为false的元素过滤掉

&#64;Test
public void testFilter(){Stream<Integer> stream &#61; Stream.of(1, 2, 3);stream.filter(e->e > 2).forEach(System.out::println);// 符合大于2的数字 -> 3
}

filter() 传入需要过滤的条件
2、map(fun) 转换元素的值&#xff0c;可以用方法引元或者lambda表达式

&#64;Test
public void testMap(){Stream<Integer> stream &#61; Stream.of(1, 2, 3);stream.map(o -> Integer.toString(o)).forEach(s->{System.out.println(s);// 1,2,3System.out.println(s.getClass());// class java.lang.String});List<Dish> dishes &#61; Arrays.asList(new Dish("beef", "100", 200, Dish.Type.MEAT),new Dish("pork", "false", 800, Dish.Type.MEAT),new Dish("rice", "true", 350, Dish.Type.OTHER));dishes.stream().map(Dish::getName).forEach(System.out::println);// beef pork rice
}

可以看到&#xff0c;使用map方法实现了Integer-> String的类型转换&#xff0c;也可以获取对象的某一属性值等等。
3、flatMap(fun) 若元素是流&#xff0c;将流摊平为正常元素&#xff0c;再进行元素转换

String [] arr &#61; {"aaa","bbb","ccc"};
Arrays.stream(arr).map(s-> s.split("")).forEach(System.out::println);// [Ljava.lang.String;&#64;33e5ccce
List<String[]> collect &#61; Arrays.stream(arr).map(s -> s.split("")).collect(Collectors.toList());

我们可以看到使用map时输出的是一个地址&#xff0c;返回的类型实际是 List 使用flatMap时

List<String> list &#61; Arrays.stream(arr).map(s -> s.split("")).flatMap(Arrays::stream).collect(Collectors.toList());
Arrays.stream(arr).map(s->s.split("")).flatMap(Arrays::stream).forEach(System.out::println);// aaabbbccc

可以看到返回的类型为List &#xff0c;将整个外层list包含的所有元素放到一个层面处理。
4、limit(n) 保留前n个元素

List<Dish> mean &#61; Arrays.asList(new Dish("pork", "false", 800, Dish.Type.MEAT),new Dish("beef", "false", 700, Dish.Type.MEAT),new Dish("chicken", "false", 400, Dish.Type.MEAT),new Dish("french fries", "true", 530, Dish.Type.OTHER),new Dish("rice", "true", 350, Dish.Type.OTHER),new Dish("season fruit", "true", 120, Dish.Type.OTHER),new Dish("pizza", "true", 550, Dish.Type.OTHER),new Dish("prawns", "false", 300, Dish.Type.FISH),new Dish("salmon", "false", 450, Dish.Type.FISH)
);
//截取前2个菜品
List<Dish> dishes &#61; mean.stream().limit(2).collect(Collectors.toList());
System.out.println(dishes.size());//2
mean.stream().limit(2).forEach(System.out::println);
//Dish{name&#61;&#39;pork&#39;, vegetarian&#61;&#39;false&#39;, calories&#61;800, type&#61;MEAT}
//Dish{name&#61;&#39;beef&#39;, vegetarian&#61;&#39;false&#39;, calories&#61;700, type&#61;MEAT}

5、skip(n) 跳过前n个元素

// 跳过前7个菜品
mean.stream().skip(7).forEach(System.out::println);
//Dish{name&#61;&#39;prawns&#39;, vegetarian&#61;&#39;false&#39;, calories&#61;300, type&#61;FISH}
//Dish{name&#61;&#39;salmon&#39;, vegetarian&#61;&#39;false&#39;, calories&#61;450, type&#61;FISH}

对于limit 和 skip 配合使用可以实现分页操作
**6、distinct() 去重 剔除重复元素 **

&#64;Test
public void testDistinct(){int[] arr &#61; {1,1,2,2,3,4,5};Arrays.stream(arr).distinct().forEach(System.out::println);// 1 2 3 4 5
}

7、sorted() 排序 默认升序

int[] arr &#61; {5,7,3,1,8,4};
Arrays.stream(arr).sorted().forEach(System.out::println);// 134578

8、sorted(Comparator) 按传入的条件排序

List<Dish> mean &#61; Arrays.asList(new Dish("pork", "false", 800, Dish.Type.MEAT),new Dish("beef", "false", 700, Dish.Type.MEAT),new Dish("chicken", "false", 400, Dish.Type.MEAT),new Dish("french fries", "true", 530, Dish.Type.OTHER),new Dish("rice", "true", 350, Dish.Type.OTHER),new Dish("season fruit", "true", 120, Dish.Type.OTHER),new Dish("pizza", "true", 550, Dish.Type.OTHER),new Dish("prawns", "false", 300, Dish.Type.FISH),new Dish("salmon", "false", 450, Dish.Type.FISH)
);
// 按菜品的卡路里排序 并打印卡路里的值
mean.stream().sorted(Comparator.comparing(Dish::getCalories)).map(Dish::getCalories).forEach(System.out::println);//120 300 350 400 450 530 550 700 800
// reversed 反转 实现倒叙排序
mean.stream().sorted(Comparator.comparing(Dish::getCalories).reversed()).map(Dish::getCalories).forEach(System.out::println);// 800 700 550 530 450 400 350 300 120

9、peek(fun) 流不变 接收一个没有返回值的λ表达式&#xff0c;可以做一些输出&#xff0c;外部处理

&#64;Test
public void testPeek(){int [] arr &#61; {1,1,2,3,4,4,5};Arrays.stream(arr).distinct().map(o-> o*2).peek(s->System.out.println("peek 做一些输出操作"&#43;s)).forEach(System.out::println);
}

peek 和 map 的区别
peek 的定义

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

熟悉lambda的都知道Consumer的实现类 应该只有一个方法&#xff0c;该方法返回类型为void。

Consumer<Integer> c &#61; i -> System.out.println("hello" &#43; i);

map的定义

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

我们发现Function 比 Consumer 多了一个 return。 map接收一个有返回值的lambda表达式&#xff0c;之后Stream的泛型类型将转换为map参数λ表达式返回的类型

Function<Integer,String> f &#61; x -> {return "hello" &#43; i;};


推荐阅读
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ... [详细]
  • 尽管使用TensorFlow和PyTorch等成熟框架可以显著降低实现递归神经网络(RNN)的门槛,但对于初学者来说,理解其底层原理至关重要。本文将引导您使用NumPy从头构建一个用于自然语言处理(NLP)的RNN模型。 ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 本文介绍如何在现有网络中部署基于Linux系统的透明防火墙(网桥模式),以实现灵活的时间段控制、流量限制等功能。通过详细的步骤和配置说明,确保内部网络的安全性和稳定性。 ... [详细]
  • JavaScript实现表格数据的实时筛选功能
    本文介绍如何使用JavaScript实现对表格数据的实时筛选,帮助开发者提高用户体验。通过简单的代码示例,展示如何根据用户输入的关键字动态过滤表格内容。 ... [详细]
  • 卷积神经网络(CNN)基础理论与架构解析
    本文介绍了卷积神经网络(CNN)的基本概念、常见结构及其各层的功能。重点讨论了LeNet-5、AlexNet、ZFNet、VGGNet和ResNet等经典模型,并详细解释了输入层、卷积层、激活层、池化层和全连接层的工作原理及优化方法。 ... [详细]
  • 本文详细介绍了Java Web应用程序中的过滤器(Filter)功能,包括其作用、实现方式及配置方法。过滤器可以在请求到达目标资源之前对其进行预处理,并在响应返回给客户端之前进行后处理。 ... [详细]
author-avatar
思念如此难受_351
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有