流的操作类型主要分为两种:中间操作符、终端操作符
Stream是Java 8 API添加的一个新的抽象,称为流Stream,以一种声明性方式处理数据集合(侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式)
中高级开发工程师必会!
一、中间操作符
User实体类(需要引入lombok,或者自己生成get、set和构造方法)
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
int id;
String name;
int age;
String address;
}
代码示例
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* 流的操作-中间操作符
* 中间操作符都是惰性化的,仅仅调用到这类方法,并没有真正开始执行,需要等到执行终端操作方法是执行,
*/
public class StreamDemo02 {
private static List<User> getUserList() {
List<User> userList = new ArrayList<>();
userList.add(new User(1,"张三",18,"上海"));
userList.add(new User(2,"王五",16,"上海"));
userList.add(new User(3,"李四",20,"上海"));
userList.add(new User(4,"张雷",22,"北京"));
userList.add(new User(5,"张超",15,"深圳"));
userList.add(new User(6,"李雷",24,"北京"));
userList.add(new User(7,"王爷",21,"上海"));
userList.add(new User(8,"张三丰",18,"广州"));
userList.add(new User(9,"赵六",16,"广州"));
userList.add(new User(10,"赵无极",26,"深圳"));
return userList;
}
public static void main(String[] args) throws IOException {
List<User> userList = getUserList();
System.out.println("------------filter 过滤--------------");
//filter 过滤 参数是Predicate函数
userList.stream().filter(user -> user.getId() > 5).collect(Collectors.toList()).forEach(System.out::println);
System.out.println("------------map 转换--------------");
//map 转换 参数是Function函数
userList.stream().map(user -> user.getAddress()).collect(Collectors.toList()).forEach(System.out::println);
System.out.println("------------distinct 去重----------------");
//distinct 去重
userList.stream().map(User::getAddress).distinct().collect(Collectors.toList()).forEach(System.out::println);
System.out.println("------------dsorted 排序----------------");
//sorted 排序 根据id倒序排列
userList.stream().sorted(Comparator.comparing(User::getId).reversed()).forEach(System.out::println);
System.out.println("------------limit 保留----------------");
//limit 保留前n个元素
userList.stream().limit(5).forEach(System.out::println);
System.out.println("------------skip 丢弃----------------");
//skip 丢弃前n个元素
userList.stream().skip(5).forEach(System.out::println);
System.out.println("------------flatMap 流处理----------------");
//flatMap 流处理
/**
* flatMap 与 map对比
* map:对流中每一个元素进行处理
* flatMap:流扁平化,让你把一个流中的“每个值”都换成另一个流,然后把所有的流连接起来成为一个流
*/
userList.stream().flatMap(user -> Arrays.stream(user.getAddress().split(","))).forEach(System.out::println);
System.out.println("------------peek 遍历处理----------------");
//peek 遍历处理
/**
* peek 和 forEach的区别
* peek:中间操作 需要配合终端操作才能执行
* forEach: 终端操作
*/
userList.stream().peek(user -> user.setId(user.getId() + 100)).forEach(System.out::println);
}
}
二、终端操作符
import entity.User;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 流的操作-终端操作符
* Stream流执行完终端操作之后,无法再执行其他动作,否则会报状态异常,
* 想要再次执行操作必须重新创建Stream流
* 通俗将终端操作后不会返回stream流,无法继续操作
*/
public class StreamDemo03 {
private static List<User> getUserList() {
List<User> userList = new ArrayList<>();
userList.add(new User(1,"张三",18,"上海"));
userList.add(new User(2,"王五",16,"上海"));
userList.add(new User(3,"李四",20,"上海"));
userList.add(new User(4,"张雷",22,"北京"));
userList.add(new User(5,"张超",15,"深圳"));
userList.add(new User(6,"李雷",24,"北京"));
userList.add(new User(7,"王爷",21,"上海"));
userList.add(new User(8,"张三丰",18,"广州"));
userList.add(new User(9,"赵六",16,"广州"));
userList.add(new User(10,"赵无极",26,"深圳"));
return userList;
}
public static void main(String[] args) throws IOException {
List<User> userList = getUserList();
System.out.println("------------collect 收集器--------------");
//collect 收集器 收集为Set
userList.stream().collect(Collectors.toSet()).stream().forEach(System.out::println);
System.out.println("------------forEach 遍历流--------------");
//forEach 遍历流
userList.stream().forEach((user)->{
user.setAddress(user.getAddress() + "处理后!");
System.out.println(user);
});
System.out.println("------------findFirst 返回第一个元素--------------");
//findFirst 返回第一个元素 年龄是16的第一个元素
System.out.println(userList.stream().filter(user -> user.getAge() == 16).findFirst());
System.out.println("------------findAny 返回任意元素--------------");
//findAny 返回任意元素
System.out.println(userList.stream().findAny().get());
System.out.println("------------count 返回流元素中的数量--------------");
//count 返回流元素中的数量
System.out.println(userList.stream().count());
System.out.println("------------sum 求和--------------");
//sum 求和 IntStream可使用 数值类流
System.out.println(userList.stream().mapToInt(User::getAge).sum());
System.out.println("------------max 最大值--------------");
//max 最大值
System.out.println(userList.stream().mapToInt(User::getAge).max().getAsInt());
System.out.println("------------min 最小值--------------");
//min 最小值
System.out.println(userList.stream().mapToInt(User::getAge).min().getAsInt());
System.out.println("------------anyMatch 是否至少匹配一个-------------");
//anyMatch 是否至少匹配一个 列表中是否存在名叫王五的中人
System.out.println(userList.stream().anyMatch(user -> "王五".equals(user.getName())));
System.out.println("------------allMatch 是否全都匹配--------------");
//allMatch 是否全都匹配 列表中的id是否全都大于0
System.out.println(userList.stream().allMatch(user -> user.getId() > 0));
System.out.println("------------noneMatch 是否全都不匹配--------------");
//noneMatch 是否全都不匹配 列表中的地址长度是否都不大于1000
System.out.println(userList.stream().noneMatch(user -> user.getAddress().length() > 1000));
System.out.println("------------reduce 结合--------------");
//reduce 可以将流中元素反复结合起来,得到一个值
System.out.println(userList.stream().reduce((user, user2) -> user));
}
}