Stream流常用的方法
User实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String name;
private Integer age;
}
// 创建集合
List<User> users = new ArrayList<>();
users.add(new User("张三", 18));
users.add(new User("李四", 22));
users.add(new User("王五", 26));
List
去重
基础去重
List<User> collect = users.stream().distinct().collect(Collectors.toList());
根据指定属性去重
// 根据 name 去重
List<User> collect = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new));
// 根据 name和age 去重
List<User> collect = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(user -> user.getName() + "-" + user.getAge()))), ArrayList::new));
排序
基础排序
List<Integer> list = Arrays.asList(1,2,3,4);
// 正序
List<Integer> list = list.stream().sorted().collect(Collectors.toList());
// 倒序
List<Integer> list = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
根据指定属性排序
// age 正序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
// age 倒序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
属性有NULL值排序
// null 值排在最后面
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge,Comparator.nullsLast(Integer::compareTo))).collect(Collectors.toList());
// null 值排在最前面
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge,Comparator.nullsLast(Integer::compareTo))).collect(Collectors.toList());
指定多个属性分别排序
// age正序 gender正序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getGender)).collect(Collectors.toList());
// age倒序 gender正序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).reversed().thenComparing(User::getGender)).collect(Collectors.toList());
过滤
// 过滤 name!=null
users.stream().filter(user -> user.getName()!=null).collect(Collectors.toList());
分页
// 第1页,每页10 分页
long skipNum = (long) (页码 - 1) * 每页数量;
users.stream().skip(skipNum).limit(每页数量).collect(Collectors.toList());
分组
// 根据 age 分组
Map<Integer, List<User>> collect = users.stream().collect(Collectors.groupingBy(User::getAge));
// 根据 age 分组,用 name 作为值
Map<Integer, String> collect = users.stream().collect(Collectors.groupingBy(User::getAge,Collectors.mapping(User::getName, Collectors.toList())));
获取指定属性的集合
// 获取 name 的集合
List<String> users = users.stream().map(User::getName).collect(Collectors.toList());
Map、List互转
使用(key1,key2)->key2表达式用于解决key重复问题;(key1,key2)->key2 表示key重复使用key2覆盖前面的,也可以保留key1的值。
// list转map(name作为key,user对象作为value)
Map<String, User> userMap = users.stream().collect(Collectors.toMap(User::getName, Function.identity(), (key1, key2) -> key2));
// list转map(name作为key,age作为value)
Map<String, Integer> userMap = users.stream().collect(Collectors.toMap(User::getName, User::getAge));
// map转list
List<User> users = userMap.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList());
根据指定字符拼接成字符串
Collectors.joining(分隔符,前缀,后缀)
String str = users.stream().map(User::getName).collect(Collectors.joining("/","(",")"));
最大值、最小值、求和、总条数
// 最大值
int max = users.stream().mapToInt(User::getAge).summaryStatistics().getMax();
Integer maxAge = users.stream().map(User::getAge).max(Integer::compare).get();
// 最小值
int min = users.stream().mapToInt(User::getAge).summaryStatistics().getMin();
Integer mixAge = users.stream().map(User::getAge).min(Integer::compare).get();
// 求和
long sum = users.stream().mapToInt(User::getAge).summaryStatistics().getSum();
Integer sumAge = users.stream().mapToInt(User::getAge).sum();
// 总条数
long count = users.stream().mapToInt(User::getAge).summaryStatistics().getCount();
long count1 = users.stream().count();
判断
检查是否至少匹配一个元素 anyMatch()
有一个年龄大于20的就返回true
boolean bool = users.stream().anyMatch(user -> user.getAge()>20);
检查是否所有值都匹配 allMatch()
全部年龄都大于20才返回true
boolean bool = users.stream().allMatch(user -> user.getAge()>20);
检查是否没有一项匹配 noneMatch()
全部年龄都不大于20才返回true
boolean bool = users.stream().noneMatch(user -> user.getAge()>20);
查找符合条件的第一个元素 findAny()
返回第一个年龄大于20的
Optional<User> userOptional=users.stream().filter(user -> user.getAge() > 20).findAny()
查找符合条件的第一个元素 findFirst()
返回第一个年龄大于20的
Optional<User> userOptional=users.stream().filter(user -> user.getAge() > 20).findFirst()
Optional类
Optional类是一个容器类,也是jdk1.8之后的新特性,代表一个值存在或者不存在。在上面的代码中findAny和findFirst可能上面元素都没找到。java8引入了Optional是为了避免出现null值的问题。
Optional对象.get()就可以获取到user对象。
findAny和findFirst区别
并行流处理,找到第一个元素在并行时限制更多。如果不关心返回的元素是哪个,使用findAny即可。
普通流listUser.stream()和并行流listUser.parallelStream()。