前言
Stream是Java1.8开始添加的新特性,大大简化了对于集合对象等的处理。
顾名思义,Stream即是流,它把输入的集合元素看作一种流,像流水线处理方式一样可以对集合元素进行筛选、排序、聚合等操作。
Stream详解
为了接下来的示例,首先定义一个User类。
public class User {
private String name;
private double height;
//为了篇幅省略构造函数 get、set方法 重写toString()方法
}
之后生成一个User List
List<User> users = new ArrayList<>();
for (int i = 0; i < 5; i++) {
User user = new User("user" + i, 120.0 + 10 * i); // name, height
users.add(user);
}
1 获取流
Java支持多种数据流获取方式。比如集合、数组、值以及文件等。最常用的数据源是集合和数组。
· 集合
List<User> users = new ArrayList<>();
Stream<User> userStream = users.stream()
· 数组
int[] intArray = {1,2,3,4};
IntStream streamInt = Arrays.stream(intArray);
2 筛选filter
过滤身高大于130的user
List userStreamFilter = users.stream().filter(s -> s.getHeight() > 130).collect(Collectors.toList());
users.forEach(s -> System.out.println("origin: " + s));
userStreamFilter.forEach(s -> System.out.println("filter: " + s));
输出:
origin: User{ name='user0', height=120.0}
origin: User{ name='user1', height=130.0}
origin: User{ name='user2', height=140.0}
origin: User{ name='user3', height=150.0}
origin: User{ name='user4', height=160.0}
filter: User{ name='user2', height=140.0}
filter: User{ name='user3', height=150.0}
filter: User{ name='user4', height=160.0}
3 去重distinct
在User类中重写equals()方法,name以及height相同的即返回true。
users.add(new User("user0", 120.0)); //添加一条重复user数据
List userStreamDistinct = users.stream().distinct().collect(Collectors.toList());
users.forEach(s -> System.out.println("origin: " + s));
userStreamDistinct.forEach(s -> System.out.println("distinct: " + s));
输出:
origin: User{ name='user0', height=120.0}
origin: User{ name='user1', height=130.0}
origin: User{ name='user2', height=140.0}
origin: User{ name='user3', height=150.0}
origin: User{ name='user4', height=160.0}
origin: User{ name='user0', height=120.0} //原始数据中有该重复数据
distinct: User{ name='user0', height=120.0}
distinct: User{ name='user1', height=130.0}
distinct: User{ name='user2', height=140.0}
distinct: User{ name='user3', height=150.0}
distinct: User{ name='user4', height=160.0}//已去掉重复数据
4 跳过前面元素skip
跳过list最前面三个user。
List userStreamSkip = users.stream().skip(3).collect(Collectors.toList());
users.forEach(s -> System.out.println("origin: " + s));
userStreamSkip.forEach(s -> System.out.println("distinct: " + s));
输出
origin: User{ name='user0', height=120.0}
origin: User{ name='user1', height=130.0}
origin: User{ name='user2', height=140.0}
origin: User{ name='user3', height=150.0}
origin: User{ name='user4', height=160.0}
skip: User{ name='user3', height=150.0}
skip: User{ name='user4', height=160.0}
5 截取前面几个元素limit
只返回前面三个user
List userStreamLimit = users.stream().limit(3).collect(Collectors.toList());
users.forEach(s -> System.out.println("origin: " + s));
userStreamLimit.forEach(s -> System.out.println("limit: " + s));
输出:
origin: User{ name='user0', height=120.0}
origin: User{ name='user1', height=130.0}
origin: User{ name='user2', height=140.0}
origin: User{ name='user3', height=150.0}
origin: User{ name='user4', height=160.0}
limit: User{ name='user0', height=120.0}
limit: User{ name='user1', height=130.0}
limit: User{ name='user2', height=140.0}
6 映射map
对流中的每个元素执行一个函数,使得元素转换成另一种类型输出。流会将每一个元素输送给map函数,并执行map中的Lambda表达式,最后将执行结果存入一个新的流中
例如获取userList中每个user的height属性
List userStreamMap = users.stream().map(User::getHeight).collect(Collectors.toList());
users.forEach(s -> System.out.println("origin: " + s));
userStreamMap.forEach(s -> System.out.println("map: " + s));
输出:
origin: User{ name='user0', height=120.0}
origin: User{ name='user1', height=130.0}
origin: User{ name='user2', height=140.0}
origin: User{ name='user3', height=150.0}
origin: User{ name='user4', height=160.0}
map: 120.0
map: 130.0
map: 140.0
map: 150.0
map: 160.0