非新手请忽略跳过
对象类定义
public class UserCourse {
int id;
String name;
int age;
String course;
int score;
}
初始化数据
List<UserCourse> userCourseList = new ArrayList<>();
UserCourse userCourse1 = new UserCourse();
userCourse1.setId(1001);
userCourse1.setName("张三");
userCourse1.setAge(17);
userCourse1.setCourse("语文");
userCourse1.setScore(85);
userCourseList.add(userCourse1);
UserCourse userCourse2 = new UserCourse();
userCourse2.setId(1002);
userCourse2.setName("张三");
userCourse2.setAge(17);
userCourse2.setCourse("数学");
userCourse2.setScore(90);
userCourseList.add(userCourse2);
UserCourse userCourse3 = new UserCourse();
userCourse3.setId(1003);
userCourse3.setName("张三");
userCourse3.setAge(17);
userCourse3.setCourse("英语");
userCourse3.setScore(95);
userCourseList.add(userCourse3);
UserCourse userCourse4 = new UserCourse();
userCourse4.setId(1004);
userCourse4.setName("李四");
userCourse4.setAge(18);
userCourse4.setCourse("语文");
userCourse4.setScore(75);
userCourseList.add(userCourse4);
UserCourse userCourse5 = new UserCourse();
userCourse5.setId(1005);
userCourse5.setName("李四");
userCourse5.setAge(18);
userCourse5.setCourse("数学");
userCourse5.setScore(100);
userCourseList.add(userCourse5);
UserCourse userCourse6 = new UserCourse();
userCourse6.setId(1006);
userCourse6.setName("李四");
userCourse6.setAge(18);
userCourse6.setCourse("英语");
userCourse6.setScore(80);
userCourseList.add(userCourse6);
UserCourse userCourse7 = new UserCourse();
userCourse7.setId(1007);
userCourse7.setName("王五");
userCourse7.setAge(19);
userCourse7.setCourse("语文");
userCourse7.setScore(90);
userCourseList.add(userCourse7);
UserCourse userCourse8 = new UserCourse();
userCourse8.setId(1008);
userCourse8.setName("王五");
userCourse8.setAge(19);
userCourse8.setCourse("数学");
userCourse8.setScore(85);
userCourseList.add(userCourse8);
UserCourse userCourse9 = new UserCourse();
userCourse9.setId(1009);
userCourse9.setName("王五");
userCourse9.setAge(19);
userCourse9.setCourse("英语");
userCourse9.setScore(95);
userCourseList.add(userCourse9);
自测用例
//构建Map<id,UserCourse>结构
Map<Integer, UserCourse> userCourseMap = userCourseList.stream().collect(Collectors.toMap(UserCourse::getId, UserCourse -> UserCourse));
userCourseMap.forEach((id, userCourse) -> System.out.println("ID: " + id + ", 映射对象userCourse: " + JSON.toJSONString(userCourse)));
//构建Map<id,courseName>结构
Map<Integer, String> idToCourseMap = userCourseList.stream().collect(Collectors.toMap(UserCourse::getId, UserCourse::getCourse));
idToCourseMap.forEach((id, courseName) -> System.out.println("ID: " + id + ", 映射字段courseName: " + courseName));
//构建Map<name,List<UserCourse>>结构
Map<String, List<UserCourse>> nameToUserCourseListMap = userCourseList.stream().collect(Collectors.groupingBy(UserCourse::getName));
nameToUserCourseListMap.forEach((name, userCourseList) -> System.out.println("name: " + name + ", 先分组userCourseList: " + JSON.toJSONString(userCourseList)));
//对每个分组的List<UserCourse>按照score降序排序
Map<String, List<UserCourse>> sortedUserCourseMapByName = nameToUserCourseListMap.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().stream()
.sorted(Comparator.comparing(UserCourse::getScore).reversed())
.collect(Collectors.toList())
));
sortedUserCourseMapByName.forEach((name, userCourseList) -> System.out.println("name: " + name + ", 再降序:userCourseList: " + JSON.toJSONString(userCourseList)));
// 按name分组并对每个分组的List<UserCourse>按照score降序排序(分组和降序写在一起)
Map<String, List<UserCourse>> sortedUserCourseMapByName2 = userCourseList.stream()
.collect(Collectors.groupingBy(
UserCourse::getName,
Collectors.collectingAndThen(
Collectors.toList(),
list -> list.stream()
.sorted(Comparator.comparing(UserCourse::getScore).reversed())
.collect(Collectors.toList())
)
));
sortedUserCourseMapByName2.forEach((name, userCourseList) -> System.out.println("name: " + name + ", 分组和降序写在一起:userCourseList: " + JSON.toJSONString(userCourseList)));
// 按name分组并对每个分组的List<UserCourse>按照score降序排序,并过滤分数小于80的
Map<String, List<UserCourse>> sortedAndFilteredUserCourseMapByName3 = userCourseList.stream()
.collect(Collectors.groupingBy(
UserCourse::getName,
Collectors.collectingAndThen(
Collectors.toList(),
list -> list.stream()
.filter(userCourse -> userCourse.getScore() >= 80) // 过滤分数小于80的
.sorted(Comparator.comparing(UserCourse::getScore).reversed()) // 按score降序排序
.collect(Collectors.toList())
)
));
sortedAndFilteredUserCourseMapByName3.forEach((name, userCourseList) -> System.out.println("name: " + name + ", 分组+过滤+降序写在一起:userCourseList: " + JSON.toJSONString(userCourseList)));
//过滤掉分数小于80的,按name分组并对每个分组的List<UserCourse>按照score降序排序
Map<String, List<UserCourse>> sortedAndFilteredUserCourseMapByName4 = userCourseList.stream()
.filter(userCourse -> userCourse.getScore() >= 80) // 过滤分数小于80的
.collect(Collectors.groupingBy(
UserCourse::getName,
Collectors.collectingAndThen(
Collectors.toList(),
list -> list.stream()
.sorted(Comparator.comparing(UserCourse::getScore).reversed()) // 按score降序排序
.collect(Collectors.toList())
)
));
sortedAndFilteredUserCourseMapByName4.forEach((name, userCourseList) -> System.out.println("name: " + name + ", 过滤+分组+降序写在一起:userCourseList: " + JSON.toJSONString(userCourseList)));
// 过滤掉分数小于85的课程
List<UserCourse> filteredUserCourses = userCourseList.stream()
.filter(userCourse -> userCourse.getScore() >= 85) // 过滤分数小于85的
.collect(Collectors.toList());
System.out.println("过滤掉分数小于85的课程,filteredUserCourses:" + JSON.toJSONString(filteredUserCourses));
// 过滤掉分数小于85的课程,然后再做id对象映射
Map<Integer,UserCourse> filteredAndIdToUserCourse = userCourseList.stream()
.filter(userCourse -> userCourse.getScore() >= 85) // 过滤分数小于85的
.collect(Collectors.toMap(UserCourse::getId,UserCourse->UserCourse));
filteredAndIdToUserCourse.forEach((id, userCourse) -> System.out.println("id: " + id + ", 过滤掉分数小于85的课程,然后再做id对象映射:userCourseList: " + JSON.toJSONString(userCourse)));
Set<String> nameSet=userCourseList.stream().collect(Collectors.mapping(UserCourse::getName,Collectors.toSet()));
System.out.println("去重后的nameSet: " + JSON.toJSONString(nameSet));
Collectors常用接口
1. toList
将流的元素收集到一个 List
中。
List<UserCourse> list = stream.collect(Collectors.toList());
2. toSet
将流的元素收集到一个 Set
中。
Set<UserCourse> set = stream.collect(Collectors.toSet());
3. toMap
将流的元素收集到一个 Map
中。需要提供键和值的映射函数。
Map<Long, UserCourse> map = stream.collect(Collectors.toMap(UserCourse::getId, Function.identity()));
4. joining
将流的字符串元素连接成一个字符串。可以指定分隔符、前缀和后缀。
String result = stream.collect(Collectors.joining(", ", "[", "]"));
5. groupingBy
根据指定的分类函数对流的元素进行分组,并将结果收集到一个 Map
中。
Map<String, List<UserCourse>> groupedByName = stream.collect(Collectors.groupingBy(UserCourse::getName));
6. partitioningBy
根据指定的谓词函数对流的元素进行分区(布尔分类),并将结果收集到一个 Map<Boolean, List<T>>
中。
Map<Boolean, List<UserCourse>> partitioned = stream.collect(Collectors.partitioningBy(userCourse -> userCourse.getScore() >= 85));
7. counting
计算流中的元素数量。
long count = stream.collect(Collectors.counting());
8. summarizingInt / summarizingDouble / summarizingLong
收集统计信息(如计数、总和、最小值、最大值、平均值)。
IntSummaryStatistics stats = stream.collect(Collectors.summarizingInt(UserCourse::getScore));
9. averagingInt / averagingDouble / averagingLong
计算流中元素的平均值
double averageScore = stream.collect(Collectors.averagingDouble(UserCourse::getScore));
10. reducing
通过指定的累加函数对流中的元素进行归约操作。
Optional<UserCourse> maxScoreCourse = stream.collect(Collectors.reducing((c1, c2) -> c1.getScore() > c2.getScore() ? c1 : c2));
11. collectingAndThen
在执行完收集操作后,再执行一个额外的转换函数。
List<UserCourse> unmodifiableList = stream.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
12. mapping
在收集之前对流的元素进行映射。
Set<String> courseNames = stream.collect(Collectors.mapping(UserCourse::getCourseName, Collectors.toSet()));
13. flatMapping
在收集之前对流的元素进行扁平化映射。
Set<String> uniqueCourseNames = stream.collect(Collectors.flatMapping(userCourse -> Arrays.stream(userCourse.getCourseName().split(",")), Collectors.toSet()));
14. teeing
将流的元素分别传递给两个不同的收集器,并将其结果组合成一个新的结果。
String summary = stream.collect(Collectors.teeing( Collectors.summingInt(UserCourse::getScore), Collectors.counting(), (sum, count) -> "Sum: " + sum + ", Count: " + count));
这些方法提供了丰富的工具来处理和转换流中的数据,使得 Java Streams API 非常强大和灵活。你可以根据具体需求选择合适的 Collector
来简化数据处理过程。
Stream常用接口
1. map
将字符串列表转换为其长度的列表。
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream().map(String::length).collect(Collectors.toList());
System.out.println(nameLengths); // 输出: [5, 3, 7] }
}
2. filter
过滤出长度大于 3 的名字。
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
List<String> filteredNames = names.stream().filter(name -> name.length() > 3).collect(Collectors.toList());
System.out.println(filteredNames); // 输出: [Alice, Charlie] }
}
3. sorted
对字符串列表进行自然排序。
public static void main(String[] args) {
List<String> names = List.of("Charlie", "Alice", "Bob");
List<String> sortedNames = names.stream().sorted().collect(Collectors.toList());
System.out.println(sortedNames); // 输出: [Alice, Bob, Charlie]
}
4. flatMap
将嵌套的列表扁平化,例如将多个列表合并为一个列表。
public static void main(String[] args) {
List<List<String>> namesList = List.of(List.of("Alice", "Bob"), List.of("Charlie", "David"));
List<String> flatNames = namesList.stream().flatMap(List::stream).collect(Collectors.toList());
System.out.println(flatNames); // 输出: [Alice, Bob, Charlie, David]
}
5. distinct
从字符串列表中去重,保留唯一的名字。
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Alice", "Charlie");
List<String> distinctNames = names.stream().distinct().collect(Collectors.toList());
System.out.println(distinctNames); // 输出: [Alice, Bob, Charlie]
}
综合示例
结合所有这些方法的综合示例:
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie", "David", "Alice");
List<String> result = names.stream()
.filter(name -> name.length() > 3)
.distinct()
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
System.out.println(result); // 输出: [ALICE, CHARLIE, DAVID]
}
这些示例展示了如何使用 Java Stream API 中的常用方法来处理和转换数据。