Java 8 API 添加了一个新的抽象称为Stream(流),以一种声明的方式处理数据
新建一个DTO用于测试
@Data
public class UserDTO {
private String userId;
private String userName;
private Integer age;
private String province;
private String city;
public UserDTO() {
}
public UserDTO(String userId, String userName, Integer age, String province, String city) {
this.userId = userId;
this.userName = userName;
this.age = age;
this.province = province;
this.city = city;
}
}
main方法执行验证
public static void main(String[] args) {
List<UserDTO> list = new ArrayList<>();
list.add(new UserDTO("111", "张三", 27, "广东", "深圳"));
list.add(new UserDTO("222", "李四", 28, "福建", "厦门"));
list.add(new UserDTO("333", "王五", 21, "广东", "深圳"));
List<UserDTO> userList = new ArrayList<>();
userList.add(new UserDTO("111", "张三", 27, "广东", "深圳"));
userList.add(new UserDTO("555", "王五", 25, "北京", "北京"));
}
1、groupingBy数据分组
使用groupingBy对集合多个字段进行分组
// 使用groupingBy对集合多个字段进行分组
Map<String, List<UserDTO>> groupMap = list.stream()
.collect(Collectors.groupingBy(a -> a.getProvince() + a.getCity()));
groupMap.forEach((k, v) -> {
System.out.println("GroupingBy key:" + k);
System.out.println("GroupingBy value:" + v);
});
输出
GroupingBy key:广东深圳
GroupingBy value:[UserDTO(userId=111, userName=张三, age=27, province=广东, city=深圳), UserDTO(userId=333, userName=王五, age=21, province=广东, city=深圳)]
GroupingBy key:福建厦门
GroupingBy value:[UserDTO(userId=222, userName=李四, age=28, province=福建, city=厦门)]
2、collect数据转换
将集合转换成map,注意:需使用唯一数据作为键,staffId如果存在重复,则报Duplicate key错误
Map<String, UserDTO> itemMap = list.stream()
.collect(Collectors.toMap(UserDTO::getUserId, item -> item));
3、filter过滤数据
使用filter获取符合条件判断的数据
List<UserDTO> filterList = list.stream()
.filter(a -> Objects.equals("张三", a.getUserName()))
.collect(Collectors.toList());
4、noneMatch对比数据
对比两个集合的差集
获取list集合和userList集合过滤掉两个集合中名字和年龄相同的数据,只返回list集合的数据
List<UserDTO> users2 = list.stream().filter(a -> userList.stream()
.noneMatch(b -> Objects.equals(a.getUserName(), b.getUserName()) && a.getAge() == b.getAge()))
.collect(Collectors.toList());
users2.forEach(a -> {
System.out.println(">>>>>user2<<<<<" + a.getUserName()+a.getProvince()+a.getCity());
});
输出:
>>>>>user2<<<<<李四福建厦门
>>>>>user2<<<<<王五广东深圳
获取userList集合和list集合过滤掉两个集合中名字和年龄相同的数据,只返回userList集合的数据
List<UserDTO> users3 = userList.stream().filter(a -> list.stream()
.noneMatch(b -> Objects.equals(a.getUserName(), b.getUserName()) && a.getAge() == b.getAge()))
.collect(Collectors.toList());
users3.forEach(a -> {
System.out.println(">>>>>users3<<<<<" + a.getUserName()+a.getProvince()+a.getCity());
});
输出:
>>>>>users3<<<<<王五北京北京
5、map集合处理
两个不同对象集合相同字段赋值,并执行其他业务处理
Long roleId = 8888L;
List<UserRoleDTO> userList = list.stream().map(a-> {
UserRoleDTO dto = new UserRoleDTO();
BeanUtils.copyProperties(a, dto);
dto.setRoleId(roleId);
return dto;
}).collect(Collectors.toList());
6、anyMatch数据判断
使用 Java Stream 中的 anyMatch 方法时,通常会涉及到对集合数据进行条件判断,以便找到是否有满足特定条件的元素
注意:每条数据的age字段必须有值,不然a.getAge() < 25会报空指针
boolean anyMatch = list.stream().anyMatch(a -> a.getAge() < 25);
判断userName都不为空的情况下,返回true
boolean noneMatch = list.stream().noneMatch(a -> a.getUserName().isEmpty());
所有元素都满足条件的情况下,allMatch 返回 true
boolean allMatch = list.stream().allMatch(a -> a.getAge() > 20);
6、flatMap集合合并
List<UserDTO> flatMap = Stream.of(list.stream(), userList.stream())
.flatMap(Function.identity()).collect(Collectors.toList());
System.out.println("flatMap size:" + flatMap.size());
flatMap size:5
7、distinct数据去重
distinct根据集合的某些字段进行去重处理
List<String> userNames = flatMap.stream().map(UserDTO::getUserName).distinct()
.collect(Collectors.toList());
System.out.println("distinct:" + userNames);
distinct:[张三, 李四, 王五]
8、sorted排序
sorted 根据age字段对集合进行正序排序
List<UserDTO> sortList = list.stream()
.sorted(Comparator.comparingInt(UserDTO::getAge)).collect(Collectors.toList());
sortList.forEach(a -> {
System.out.println("sorted:" + a.getUserName()+a.getAge());
});
sorted:王五21
sorted:张三27
sorted:李四28
根据age字段进行倒序排序
list.sort((u1, u2) -> Integer.compare(u2.getAge(), u1.getAge()));
list.forEach(a -> {
System.out.println("Reverse order:" + a.getUserName()+a.getAge());
});
Reverse order:李四28
Reverse order:张三27
Reverse order:王五21
9、reduce运算
reduce对集合某个字段进行运算求和
int totalAge = list.stream().mapToInt(UserDTO::getAge).reduce(0, Integer::sum);
Total age:76