Java Stream流
创建流
Collection.stream() / Collection.parallelStream():从集合生成流,后者为并行流。
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流
Arrays.stream(T[] array):从数组生成流。
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);
IntStream.range(int startInclusive, int endExclusive):生成一个包含从startInclusive到endExclusive(不包括)的整数序列的流。
Stream.of(T… values):从给定值创建流。
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);
stream2.forEach(System.out::println); // 0 2 4 6 8 10
Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
stream3.forEach(System.out::println);
中间操作
filter 过滤
filter:用于对Stream流中的数据进行过滤
filter(Predicate<? super T>predicate)
filter方法的参数Predicate是一个函数式接口,可以使用lambda表达式
Predicate中的抽象方法
boolean test(T t)
List<User> user1 = new ArrayList<>();
// 基础
for (User user : users) {
if (user.getId()%2==0){
user1.add(user);
}
}
//1:lambda
List<User> user2 = users.stream().filter((user)->user.getId()%2==0).collect(Collectors.toList());
//2: 匿名内部类 重写 Predicate#test
List<User> user3 = users.stream().filter(new Predicate<User>() {
@Override
public boolean test(User user) {
return user.getId()%2==0;
}
}).collect(Collectors.toList());
//3: 方法引用 需要在 User类中 新增boolean isEven(User user) 方法
//List<User> user4 = users.stream().filter(User::isEven).collect(Collectors.toList());
distinct 去重
list1.stream().distinct().collect(Collectors.toList());
注:对于基本数据类型通过 == 判定值是否相同。引用数据类型通过其 equals() 方法判定。
limit 截取
limit:用于截取流中的元素
limit可以对流进行截取,只取用前n个
limit(long maxSize); [0,maxSize)
参数是一个long型,如果集合当前长度大于参数则进行截取,否则不进行操作
limit是一个延迟方法,可以继续使用Stream流方法
list1.stream().limit(2).collect(Collectors.toList());
skip 跳过
skip :用于截取流中的元素
skip 可以对流进行截取,只取用前n个
skip (long minSize); [minSize,-1]
参数是一个long型,如果集合当前长度大于参数则进行截取,否则不进行操作
list1.stream().skip(2).collect(Collectors.toList());
sorted 排序
sorted 对流中的内容进行排序
对于基本数据类型直接比较排序
对于对象则需要对象实现对应的 compareTo 接口才能直接调用比较方法
list.stream().sorted().collect(Collectors.toList()); // 默认升序
list.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());
list.stream().sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.toList());// 根据返回值判定 正-升,0-等,负-降
list.stream().sorted(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
}).collect(Collectors.toList());
//对于实体类
users.stream().sorted().collect(Collectors.toList()); //该类必须实现 compareTo 接口
users.stream().sorted(Comparator.comparing(User::getId)).collect(Collectors.toList());
users.stream().sorted((o1, o2) -> o1.getAccount().compareTo(o2.getAccount())).collect(Collectors.toList());
users.stream().sorted(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getId().compareTo(o2.getId());
}
}).collect(Collectors.toList());
reduce统计
users.stream().map(User::getId).collect(Collectors.toList());
users.stream().map(user -> user.getId()).reduce((o1, o2) -> o1+o2);
终止操作
forEach遍历
users.stream().forEach();
list 转 list
最终结果或流内容提取
list.stream().map(User::getId).collect(Collectors.toList());```
List 转 Map
从流内容中获取关注部分
Map<Long, User> collect = users.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));
anyMatch 短路匹配
匹配到一个就返回 true
users.stream().anyMatch(user -> user.getName().length()==3)
allMatch 全部匹配
所有的都要满足条件才返回true
sers.stream().allMatch(user->user.getId()>1)
findAny/findFirst 查找
//随机获取流中的一个元素,串行流为第一个,并行流可能随机
Optional<User> any = users.stream().findAny();
User user1 = any.get();
//ifPresent 如果存在则执行
users.stream().findAny().ifPresent(user -> System.out.println(user));
//findFirst 不论串行、并行都获取第一个
users.stream().findFirst().ifPresent(user -> System.out.println(user));
收集齐中joining() 方法
list.stream().map(String::valueOf).collect(Collectors.joining("-"));
users.stream().map(user -> user.getName()).collect(Collectors.joining("-"));
0-1-2-3-4-5-6-7-8-9
岇鶯翰-逼隗埈蝠-飇冼剉-丟诈乴喪-餢鞋損-辶陀膗葷-铚鈭膕-痷鰎墕熢-釅烸麉-搂軄汿榿
分组 Collectors.groupingBy()
items.stream().collect(Collectors.groupingBy(Function.identity()));
list.stream().collect(Collectors.groupingBy(User::getSex));
Map<String, Long> result2 = items.stream().collect(
Collectors.groupingBy(
Function.identity(), Collectors.counting()
)
);
最值max,min
从流中获取最大的值
list.stream().max(Comparator.comparing(Integer::intValue)).get();// 9
users.stream().max(Comparator.comparing(User::getId)).get(); // id10
users.stream().min(Comparator.comparing(User::getAccount)).get(); // id9
users.stream().max(((o2, o1) -> o1.getId().compareTo(o2.getId()))).get(); //id 1
users.stream().min(((o2, o1) -> o1.getId().compareTo(o2.getId()))).get(); //id 10
注:需要传入一个比较器,因此取到的最大值不一定就是真的最大值,根据你的比较器做的选值(源码如下截图);