引言

  Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

转自:https://blog.csdn.net/y_k_y/article/details/84633001

特点:

1 . 不是数据结构,不会保存数据。

2. 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(保留意见:毕竟peek方法可以修改流中元素)

3. 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。

创建流

// 获取顺序流
Stream stream = new ArrayList().stream();
// 获取并行流
Stream parallelStream = new ArrayList().parallelStream();
// 数组转成流
Integer[] nums = {1,2,3};
Stream<Integer> streamArray = Arrays.stream(nums);

赋值

// of方法直接赋值
Stream<Integer> stream1 = Stream.of(1,2,3,4,5);
stream1.forEach(System.out::println); // 1 2 3 4 5

// iterate生成生成无限顺序有序流,主要作用是抽象迭代逻辑
Stream<Integer> stream2 = Stream.iterate(2, x -> x * 2).limit(5);
stream2.forEach(System.out::println); // 2 4 8 16 32

// generate生成无限顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。
Stream<Integer> stream3 = Stream.generate(new Random()::nextInt).limit(2);
stream3.forEach(System.out::println); //15356208 -2042159

筛选与切片

filter:过滤流中的某些元素 limit(n):获取n个元素 skip(n):跳过n元素 distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素

Integer[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10};
Stream<Integer> streamArray = Arrays.stream(nums);
Stream<Integer> result = streamArray
.distinct() // 去重 1 2 3 4 5 6 7 8 9 10
.filter(i -> (i > 2)) // 筛选出值>2的元素 3 4 5 6 7 8 9 10
.skip(2) // 跳过前2个元素 5 6 7 8 9 10
.limit(4); // 获取前4个元素 5 6 7 8

映射

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

Integer[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10};
Stream<Integer> streamArray = Arrays.stream(nums);
List<String> strings = streamArray
.map(String::valueOf) // 通过String.valueOf()方法将各个元素转为字符串
.collect(Collectors.toList()); // 将流转为List集合

flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

Stream<String> streamArray2 = Stream.of("1.2.3", "4.5.6", "7.8.9");
List<String> result = streamArray2
.flatMap(s -> Arrays.stream(s.split("\\."))) //将流中的每个值都换成另一个流,然后分割
.collect(Collectors.toList());
// 1 2 3 4 5 6 7 8 9

排序

sorted():自然排序,流中元素需实现Comparable接口

List<String> list = Arrays.asList("a", "d", "c", "b", "x");
List<String> result = list.stream()
.sorted()
.collect(Collectors.toList());
// a b c d x

sorted(Comparator com):定制排序,自定义Comparator排序器

Person s1 = new Person("aa", 10);
Person s2 = new Person("bb", 20);
Person s3 = new Person("aa", 30);
Person s4 = new Person("dd", 40);
List<Person> personList = Arrays.asList(s1, s2, s3, s4);
//自定义排序:先按姓名升序,姓名相同则按年龄升序
personList.stream().sorted(
      (o1, o2) -> {
           if (o1.getName().equals(o2.getName())) {
               return o1.getAge() - o2.getAge();
          } else {
               return o1.getName().compareTo(o2.getName());
          }
      }
).forEach(person -> System.out.println(person.getName()));

消费

peek:如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值

Person s1 = new Person("aa", 10);
Person s2 = new Person("bb", 20);
Person s3 = new Person("aa", 30);
Person s4 = new Person("dd", 40);
List<Person> personList = Arrays.asList(s1, s2, s3, s4);

personList.stream()
.peek(person -> person.setAge(100))
.forEach(person -> System.out.println(person.getName()+":"+person.getAge()));

匹配

allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
// 里面的元素是否都满足>10这个条件
boolean result = integers.stream().allMatch(i -> i > 10); // false

noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 里面的元素是否都 不 满足>10这个条件
boolean result = list.stream().noneMatch(i -> i > 10); // true

anyMatch:接收一个 Predicate 函数,只要流中存在元素满足该断言则返回true,否则返回false

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
// 里面的元素是否存在满足>10这个条件
boolean result = list.stream().anyMatch(i -> i > 10); // true

findFirst:返回流中第一个元素

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
// Optional对象常用于解决空指针问题
Optional<Integer> optional = list.stream().findFirst();
System.out.println(optional.get()); // 1

count:返回流中元素的总个数

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
Long result = list.stream().count();
System.out.println(result); // 6

max:返回流中元素最大值

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
Integer max = list.stream().max(Integer::compareTo).get(); // 11

min:返回流中元素最小值

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 11);
Integer min = list.stream().min(Integer::compareTo).get(); // 1

reduce

Optional<T> reduce(BinaryOperator<T> accumulator)

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> optional = list.stream().reduce((x1, x2) -> x1 + x2);
System.out.println(optional.get()); // 21(为流中元素的和)
// 等效于
// Optional<Integer> optional = list.stream().reduce(Integer::sum);

T reduce(T identity, BinaryOperator<T> accumulator)

identity:返回实例 accumulator:累加器

String[] strings = {"a", "b", "c", "d", "e"};
String reduce2 = Arrays.stream(strings).reduce("", (a, b) -> {
if (!"".equals(a)) {
return a + "|" + b;
} else {
return b;
}
});
/**
* 执行流程:
* 第一个元素identity的值为"",因此a的初始值为"",b的初始值为流中第一个元素"a"
* 第一次执行之后得到结果"a",然后执行结果的值赋给a,流中第二个元素的值"b"赋给b
* 第二次执行之后得到结果"a|b",然后以此类推
*/
System.out.println(reduce2); // a|b|c|d|e

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

identity:返回实例 accumulator:累加器 combiner:组合器

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24);
Integer v2 = list.stream().reduce(0,
(x1, x2) -> {
System.out.println("stream accumulator: x1:" + x1 + " x2:" + x2);
return x1 - x2;
},
// 第三个参数---参数的数据类型必须为返回数据类型,改参数主要用于合并多个线程的result值
//(Stream是支持并发操作的,为了避免竞争,对于reduce线程都会有独立的result)
(x1, x2) -> {
System.out.println("stream combiner: x1:" + x1 + " x2:" + x2);
return x1 * x2;
});
System.out.println(v2); // -300

关于Stream的使用的更多相关文章

  1. SQL Server-聚焦查询计划Stream Aggregate VS Hash Match Aggregate(二十)

    前言 之前系列中在查询计划中一直出现Stream Aggregate,当时也只是做了基本了解,对于查询计划中出现的操作,我们都需要去详细研究下,只有这样才能对查询计划执行的每一步操作都了如指掌,所以才 ...

  2. Node.js:理解stream

    Stream在node.js中是一个抽象的接口,基于EventEmitter,也是一种Buffer的高级封装,用来处理流数据.流模块便是提供各种API让我们可以很简单的使用Stream. 流分为四种类 ...

  3. node中的Stream-Readable和Writeable解读

    在node中,只要涉及到文件IO的场景一般都会涉及到一个类-Stream.Stream是对IO设备的抽象表示,其在JAVA中也有涉及,主要体现在四个类-InputStream.Reader.Outpu ...

  4. nodejs中流(stream)的理解

    nodejs的fs模块并没有提供一个copy的方法,但我们可以很容易的实现一个,比如: var source = fs.readFileSync('/path/to/source', {encodin ...

  5. Node学习笔记(一):stream流操作

    NodeJs中谈及较多的可能就是Stream模块了,先写一个简单的ajax回调 $.post("index.php",{data:'aaa',order:'ccc'},functi ...

  6. Stream

    Stream的好处 1.Stream AP的引入弥补了JAVA函数式编程的缺陷.2.Stream相比集合类占用内存更小:集合类里的元素是存储在内存里的,Stream里的元素是在访问的时候才被计算出来. ...

  7. Stream流

    在Node中,存在各式各样不同的数据流,Stream(流)是一个由不同对象实现的抽象接口.例如请求HTTP服务器的request是一个 流,类似于stdout(标准输出):包括文件系统.HTTP 请求 ...

  8. [LeetCode] Data Stream as Disjoint Intervals 分离区间的数据流

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  9. [LeetCode] Moving Average from Data Stream 从数据流中移动平均值

    Given a stream of integers and a window size, calculate the moving average of all integers in the sl ...

  10. [LeetCode] Find Median from Data Stream 找出数据流的中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

随机推荐

  1. MyBatis源码分析(三):MyBatis初始化(配置文件读取和解析)

    一. 介绍MyBatis初始化过程 项目是简单的Mybatis应用,编写SQL Mapper,还有编写的SqlSessionFactoryUtil里面用了Mybatis的IO包里面的Resources ...

  2. 数字设计中的时钟与约束(gate)

    转载:https://www.cnblogs.com/IClearner/p/6440488.html 最近做完了synopsys的DC workshop,涉及到时钟的建模/约束,这里就来聊聊数字中的 ...

  3. sum-root-to-leaf-numbers leetcode C++

    Given a binary tree containing digits from0-9only, each root-to-leaf path could represent a number. ...

  4. hdu 1158 Employment Planning(DP)

    题意: 有一个工程需要N个月才能完成.(n<=12) 给出雇佣一个工人的费用.每个工人每个月的工资.解雇一个工人的费用. 然后给出N个月所需的最少工人人数. 问完成这个项目最少需要花多少钱. 思 ...

  5. 微服务之十四如何在 Ocelot 网关中配置多实例 Swagger 访问

    一.介绍 当我们开发基于微服务的应用程序的时候,有一个环节总是跳不过去的,那就是要创建 WebApi,然后,我们的应用程序基于 WebApi 接口去访问.在没有 Swagger 以前,我们开发好了 W ...

  6. Spark的安装及其配置

    1.Spark下载 https://archive.apache.org/dist/spark/ 2.上传解压,配置环境变量 配置bin目录 解压:tar -zxvf spark-2.4.5-bin- ...

  7. The 'stream().forEach()' chain can be replaced with 'forEach()' (may change semantics)

    对集合操作时,因不同的写法Idea经常会提示:The 'stream().forEach()' chain can be replaced with 'forEach()' (may change s ...

  8. map2bean & bean2map

    1,自己实现: /** * @author xx * @since 2020/7/8 */ @Slf4j public class JavaBeanUtils { /** * 实体类转map * 效率 ...

  9. SqlServer新建表操作DDL

    创建新表:1,五要素 2,not null 3,默认值 4,字段注释,表名称 5,索引 6,指定约束名称 -- ------------------------------ Table structu ...

  10. C++中简单使用HP-Socket

    目录 简介 使用方式 实现简单线程池 实现TCP客户端 实现TCP服务端 实现Http客户端 附件 简介 HP-Socket 是一套通用的高性能 TCP/UDP /HTTP 通信 框架 ,包含服务端组 ...