JDK8 stream 流的简单使用
- 2020年4月15日
- 排序,分组,遍历,求和,去重等
测试Demo 实体
package com.ezhiyang.controller;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Demo {
private String name;
private Integer age;
}
- 使用了lombok 插件
- @Data 所有属性的get和set方法,toString(), hashCode(), equals()
- @AllArgsConstructor 生成含所有属性的构造函数
- @NoArgsConstructor 生成无参构造
测试
@Test
public void testStream() {
List<Demo> list = Lists.newArrayList(new Demo("张三", 15), new Demo("李四", 20));
System.out.println("list: " + JSONObject.toJSONString(list));
List<Demo> collect = list.stream().filter(demo -> demo.getAge() > 15).collect(Collectors.toList());
System.out.println("过滤 age > 15 data: " + JSONObject.toJSONString(collect));
Map<String, List<Demo>> listMap = list.stream().collect(Collectors.groupingBy(demo -> demo.getName()));
System.out.println("按名字分组 listMap: " + JSONObject.toJSONString(listMap));
list.stream().forEach(demo -> {
System.out.print("name: ");
System.out.println(demo.getName());
});
collect.clear();
collect = list.stream().sorted((d1, d2) -> {
return d2.getAge().compareTo(d1.getAge());
}).collect(Collectors.toList());
System.out.println("按age倒序 collect: " + JSONObject.toJSONString(collect));
collect.clear();
collect = list.stream()
.sorted(Comparator.comparing(Demo::getAge))
.collect(Collectors.toList());
System.out.println("按age正序 collect: " + JSONObject.toJSONString(collect));
collect.clear();
collect = list.stream()
.sorted(Comparator.comparing(Demo::getAge).reversed())
.collect(Collectors.toList());
System.out.println("按age倒叙 collect: " + JSONObject.toJSONString(collect));
Integer sum = list.stream().map(Demo::getAge).reduce(0, (a, b) -> a + b);
System.out.println("求和 sum: " + sum);
Integer sum = list.stream()
.filter(e ->(e.getAge() != null))
.map(Demo::getAge).reduce(0, Integer::sum);
List<Integer> list = Lists.newArrayList(1, null, 3);
Integer reduce = list.stream()
.filter(x -> x != null)
.reduce(Integer::sum).get();
}
list: [{"age":15,"name":"张三"},{"age":20,"name":"李四"}]
过滤 age > 15 data: [{"age":20,"name":"李四"}]
按名字分组 listMap: {"李四":[{"age":20,"name":"李四"}],"张三":[{"age":15,"name":"张三"}]}
name: 张三
name: 李四
按age倒序 collect: [{"age":20,"name":"李四"},{"age":15,"name":"张三"}]
求和 sum: 35
按对象属性值去重
@Data
@AllArgsConstructor
public class User {
private Long id;
private String name;
private Integer sex;
private String email;
}
- 测试, 注意去重属性为空或者null 则会报错,先过滤空/null
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User(1L, "张三", 1, "1111@qq.com"));
users.add(new User(2L, "大漂亮", 2, "2222@qq.com"));
users.add(new User(3L, "大漂亮", 1, "3333@qq.com"));
if (!CollectionUtils.isEmpty(users)) {
List<User> list = users.stream()
.filter(c -> !StringUtils.isEmpty(c.getName()))
.filter(distinctByKey(user -> user.getName())).collect(Collectors.toList());
System.out.println(list);
}
}
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
输出结果: [User(id=1, name=张三, sex=1, email=1111@qq.com), User(id=2, name=大漂亮, sex=2, email=2222@qq.com)]
list 转 map
Map<String, User> map = list.stream().collect(Collectors.toMap(User::getId, Function.identity()));
当id出现重复的时候会报错,
- 可以用 Collectors.toMap(keyMapper, valueMapper, mergeFunction) 的重载方法解决, 用后面的值覆盖前面的值
Map<String, User> map = list.stream().collect(Collectors.toMap(User::getId, u -> u, (u1, u2) -> u1));