数据处理常用到的一些Java 8中Stream操作

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班)
*/
相关推荐
10km4 天前
java: HashMap.merge 的 Null 值陷阱:为什么 Stream API 会抛出 NPE
java·stream·hashmap·merge
云雾J视界15 天前
多Stream并发实战:用流水线技术将AIGC服务P99延迟压降63%
aigc·api·cpu·stream·gpu·cuda·多并发
颜颜yan_18 天前
基于CANN多Stream异步执行的智能推理管道:突破传统串行瓶颈
运维·架构·stream·昇腾·cann
程序员三明治2 个月前
选 Redis Stream 还是传统 MQ?队列选型全攻略(适用场景、优缺点与实践建议)
java·redis·后端·缓存·rocketmq·stream·队列
花伤情犹在2 个月前
Java Stream 高级应用:优雅地扁平化(FlatMap)递归树形结构数据
java·stream·function·flatmap
sg_knight2 个月前
Spring Cloud与RabbitMQ深度集成:从入门到生产级实战
java·spring boot·spring·spring cloud·消息队列·rabbitmq·stream
DN金猿2 个月前
java8提取list中对象有相同属性值的对象或属性值
java·list·stream·java8
mask哥3 个月前
详解flink性能优化
java·大数据·微服务·性能优化·flink·kafka·stream
中草药z3 个月前
【Stream API】高效简化集合处理
java·前端·javascript·stream·parallelstream·并行流