java stream 有点_关于Java8Stream流的使用

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据,将要处理的元素集合看作一种流

流在管道中传输,并且可以在管道的节点上进行处理,比如筛选、排序、聚合等,在管道中经过中间操作的处理后,最后由最终操作得到前面处理的结果。

总而言之,流的使用一般包括三件事:

一个数据源(如集合)来执行一个查询;

一个中间操作链,形成一条流的流水线;

一个终端操作,执行流水线,并生成结果。

中间操作,比如

filter() 、 map() 、sorted()、skip()、peek

终端操作,比如

allMatch()、anyMatch()、noneMatch()、forEach()、collect()、count()

流有两大特点,流水线(流水线的操作可以看作对数据源进行数据库式查询)和内部迭代,使用Stream API 可以写出更简洁、易读、灵活和性能更好的代码

在 Java 8 中, 集合接口有两个方法来生成流:

stream() − 为集合创建串行流。

parallelStream() − 为集合创建并行流

通过简单的例子熟悉stream的使用

创建一个User类并进行各种stream流操作

@Data

@AllArgsConstructor

public class User {

public Long id;

private String name;

private Integer age;

private Double grades;

private String sex;

/**

* 季度平时分

*/

private String usualGrades;

}

复制代码

流操作

// 查询成绩及格的用户的姓名

List nameList1 = users.stream().filter(x -> x.getGrades() > 60).map(User::getName).collect(Collectors.toList());

// 查询成绩前三(成绩相同,id较小的靠前)的姓名

List nameList2 = users.stream().sorted(Comparator.comparingDouble(User::getGrades).reversed().thenComparingLong(User::getId))

.limit(3).map(User::getName).collect(Collectors.toList());

// 统计男生数量

long num = users.stream().filter(x -> x.getSex().equals("男")).count();

//统计全班的平时分总和

Integer collect = users.stream().map(x -> x.getUsualGrades().split(",")).flatMap(Arrays::stream).collect(Collectors.summingInt(x -> Integer.parseInt(x)));

// 查看班上是否一位叫小明的同学

boolean flag = users.stream().anyMatch(x -> x.getName().equals("小明"));

// 查看全班同学是否都以"小"开头

boolean flag2 = users.stream().allMatch(x -> x.getName().startsWith("小"));

// 打印所有信息

users.stream().forEach(System.out::println);

复制代码

通过上述操作,也简单了解一些流的操作

filter 接受Lambda,从流中排除某些元素或者提取某些元素

map 接受一个Lambda,将元素转换成其他形式或提取元素

collect 将流转换为其他形式

sorted 将某些元素进行排序

limit 截断流,使其元素不超过给定数量

flatMap 将每个映射流的内容分裂成多个同样的流(一转多,比如:上述实例,每个同学有一个季度平时分【有三个分组成】,现在把他们都提取出来,变成一个个的分数)

anyMatch 匹配上任何一个则返回 Boolean

allMatch 匹配所有的元素则返回 Boolean

findAny 查找任何一个就返回 Optional

findFirst 查找到第一个就返回 Optional

forEach 遍历所有信息

还有挺多功能强大的流操作值得我们去发现,在上述操作,发现大部分操作都是接受一个Laombda表达式的语句,点击进入看源码我们能发现传入的是一个函数式接口,比如filter,传入是Predicate接口,其中只有一个方法test,传入一个参数,返回boolean类型

函数式接口

一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,一般通过FunctionalInterface这个注解来表明某个接口是一个函数式接口,可以被隐式转换为 lambda 表达式。

常用的函数式接口:

Consumer 顾名思义,Consumer的意思就是消费,默认方法是 void accept(T t)【代表了接受一个输入参数并且无返回的操作】,流操作forEach() 就用到

Function 功能或者函数 ,默认方法是 R apply(T t)【接受一个输入参数,返回一个结果】 ,在流操作map()用到

Predicate 断言,默认方法是boolean test(T t)【接受一个输入参数,返回一个布尔值结果】,流操作filter() 用到

Supplier 提供、供应,默认方法是T get()【无参数,返回一个结果】

BiConsumer 代表了一个接受两个输入参数的操作,并且不返回任何结果

BiFunction 代表了一个接受两个输入参数的方法,并且返回一个结果

IntConsumer 接受一个int类型的输入参数,无返回值

IntToDoubleFunction 接受一个int类型输入,返回一个double类型结果

ToIntFunction 接受一个输入参数,返回一个int类型结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值