数据处理常用到的一些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班)
*/
相关推荐
程序员三明治3 天前
选 Redis Stream 还是传统 MQ?队列选型全攻略(适用场景、优缺点与实践建议)
java·redis·后端·缓存·rocketmq·stream·队列
花伤情犹在16 天前
Java Stream 高级应用:优雅地扁平化(FlatMap)递归树形结构数据
java·stream·function·flatmap
sg_knight1 个月前
Spring Cloud与RabbitMQ深度集成:从入门到生产级实战
java·spring boot·spring·spring cloud·消息队列·rabbitmq·stream
DN金猿1 个月前
java8提取list中对象有相同属性值的对象或属性值
java·list·stream·java8
mask哥2 个月前
详解flink性能优化
java·大数据·微服务·性能优化·flink·kafka·stream
中草药z2 个月前
【Stream API】高效简化集合处理
java·前端·javascript·stream·parallelstream·并行流
mask哥2 个月前
详解kafka streams(二)
java·大数据·微服务·flink·kafka·stream·流式操作
上单带刀不带妹2 个月前
Node.js 的流(Stream)是什么?有哪些类型?
node.js·stream·js
ruan1145144 个月前
Java Lambda 类型推断详解:filter() 方法与 Predicate<? super T>
java·开发语言·spring·stream