Java8的Stream流对数据处理很方便,最近用得很多,整理了一下使用频率比较高的几种操作
【字符串集合】
java
List<String> list = new ArrayList<>();
Collections.addAll(list, "刘备", "关羽", "张飞", "诸葛亮", "吕布", "曹操", "曹操");
查看集合中是否存在某个字符串
java
boolean b = list.stream().anyMatch("张飞"::equals);
// true
System.out.println(b);
去重
java
List<String> collect = list.stream().distinct().collect(Collectors.toList());
// [刘备, 关羽, 张飞, 诸葛亮, 吕布, 曹操]
System.out.println(collect);
// 乱序:[关羽, 张飞, 吕布, 刘备, 诸葛亮, 曹操]
Set<String> collect1 = list.stream().collect(Collectors.toSet());
System.out.println(collect1);
// 乱序:[关羽, 张飞, 吕布, 刘备, 诸葛亮, 曹操]
Set<String> set = new HashSet<>(list);
System.out.println(set);
过滤
java
List<String> collect2 = list.stream()
.filter(o -> "曹操".equals(o) || o.startsWith("张"))
.collect(Collectors.toList());
// [张飞, 曹操, 曹操]
System.out.println(collect2);
计数
java
long count = list.stream().filter("曹操"::equals).count();
// 2
System.out.println(count);
【对象集合】
java
List<Student> studentList = new ArrayList<>();
Student student1 = Student.builder().no("1001").name("张三").gender("女").age(18).address("第一大道").classroom("202501班").build();
Student student2 = Student.builder().no("1002").name("李四").gender("女").age(18).address("第一大道").classroom("202501班").build();
Student student3 = Student.builder().no("1003").name("王五").gender("女").age(18).address("第二大道").classroom("202502班").build();
Student student4 = Student.builder().no("1004").name("赵六").gender("女").age(18).address("第三大道").classroom("202502班").build();
Student student5 = Student.builder().no("1005").name("彭于晏").gender("男").age(25).address("第四大道").classroom("202501班").build();
Student student6 = Student.builder().no("1006").name("胡歌").gender("男").age(25).address("第四大道").classroom("202502班").build();
Collections.addAll(studentList, student1, student2, student3, student4, student5, student6);
把对象的某个属性收集为list
java
List<String> nameList = studentList.stream().map(Student::getName).collect(Collectors.toList());
// [张三, 李四, 王五, 赵六, 彭于晏, 胡歌]
System.out.println(nameList);
按某个属性分组
java
// 按班级分组
Map<String, List<Student>> classRoomMap = studentList.stream().collect(Collectors.groupingBy(Student::getClassroom));
for (Map.Entry<String, List<Student>> stringListEntry : classRoomMap.entrySet()) {
System.out.println(stringListEntry.getKey());
System.out.println(stringListEntry.getValue());
}
/*
202502班
[Student(no=1003, name=王五, age=18, gender=女, address=第二大道, classroom=202502班), Student(no=1004, name=赵六, age=18, gender=女, address=第三大道, classroom=202502班), Student(no=1006, name=胡歌, age=25, gender=男, address=第四大道, classroom=202502班)]
202501班
[Student(no=1001, name=张三, age=18, gender=女, address=第一大道, classroom=202501班), Student(no=1002, name=李四, age=18, gender=女, address=第一大道, classroom=202501班), Student(no=1005, name=彭于晏, age=25, gender=男, address=第四大道, classroom=202501班)]
*/
按两个属性做map映射分组
java
Map<String, List<Student>> addressAndclassRoomMap = studentList.stream().collect(
// 分组条件:【地址、班级】,中间拼接下划线,方便分割查看而为之
Collectors.groupingBy(
o -> o.getAddress() + "__" + o.getClassroom(),
Collectors.toList()
)
);
for (Map.Entry<String, List<Student>> stringListEntry : addressAndclassRoomMap.entrySet()) {
System.out.println(stringListEntry.getKey());
System.out.println(stringListEntry.getValue());
}
/*
第三大道__202502班
[Student(no=1004, name=赵六, age=18, gender=女, address=第三大道, classroom=202502班)]
第二大道__202502班
[Student(no=1003, name=王五, age=18, gender=女, address=第二大道, classroom=202502班)]
第四大道__202501班
[Student(no=1005, name=彭于晏, age=25, gender=男, address=第四大道, classroom=202501班)]
第四大道__202502班
[Student(no=1006, name=胡歌, age=25, gender=男, address=第四大道, classroom=202502班)]
第一大道__202501班
[Student(no=1001, name=张三, age=18, gender=女, address=第一大道, classroom=202501班), Student(no=1002, name=李四, age=18, gender=女, address=第一大道, classroom=202501班)]
*/
按对象的某个属性为key,另一个属性为value做map映射
java
// 学号做为key,名字做为value(这种分组在数据只填某个字段,另一个字段需要后台自动填充的场景做映射很好用)
Map<String, String> noAndNameMap = studentList.stream().collect(Collectors.toMap(
Student::getNo,
Student::getName,
(o, t) -> o
));
for (Map.Entry<String, String> entry : noAndNameMap.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
/*
1006:胡歌
1005:彭于晏
1004:赵六
1003:王五
1002:李四
1001:张三
*/
按某个属性符合某种情况过滤(多过滤 &&)
java
List<Student> filterList = studentList.stream()
// .filter(o -> "202501班".equals(o.getClassroom()))
// .filter(o -> "男".equals(o.getGender()))
// 写法效果同上
.filter(o -> "男".equals(o.getGender()) && "202501班".equals(o.getClassroom()))
.collect(Collectors.toList());
// Student(no=1005, name=彭于晏, age=25, gender=男, address=第四大道, classroom=202501班)
filterList.forEach(System.out::println);
计数
java
// 为男生的个数
long count = studentList.stream().filter(o -> "男".equals(o.getGender())).count();
// 2
System.out.println(count);
按照某个属性去重
1.按对象的某个属性去重并把该属性值收集成list
java
// 按照班级去重并把班级收集到list中
List<String> distinctList = studentList.stream().map(Student::getClassroom).distinct().collect(Collectors.toList());
// [202501班, 202502班]
System.out.println(distinctList);
2.对象只按照某个属性进行去重
java
List<Student> distinctByFieldList = studentList.stream().collect(
Collectors.collectingAndThen(
// 按照班级去重,只保留第一个出现的
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getClassroom))),
ArrayList::new
)
);
distinctByFieldList.forEach(System.out::println);
/*
Student(no=1001, name=张三, age=18, gender=女, address=第一大道, classroom=202501班)
Student(no=1003, name=王五, age=18, gender=女, address=第二大道, classroom=202502班)
*/