展示如何使用Java 8的Stream API。这个示例包含了多个常见的Stream操作,如过滤、映射、排序、分组、去重等
- filter是筛选出需要的元素
- map是把流的对象元素映射为特定元素,可能是其中一个字段,或者是你自定义的类型
- sorted是Stream()的方法,是新的元素列表的排序后的结果,不修改原有的列表!!
- collect方法是收集前面操作完了之后的元素为一个列表,收集为列表完了之后可以调用列表方法,比如说是sort方法
- groupingBy是分组,比如下面按照字符串长度归类不同字符串,长度为5的一组,长度为6的另外一组
java">List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");Map<Integer, List<String>> collect = words.stream().collect(Collectors.groupingBy(String::length));System.out.println(collect);
groupingBy着重讲解
统计每个年龄段的人叫什么名字
java">package AAA;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;import static java.util.Collections.sort;
class Person {public String name;public int age;Person(String name, int age) {this.name = name;this.age = age;}public int getAge() {return age;}public String getName() {return name;}@Overridepublic String toString() {return name + ": " + age;}
}
public class Main5 {public static void main(String[] args) {// 创建一个Person对象列表List<Person> people = new ArrayList<>();// 手动插入100个Person对象people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 30));people.add(new Person("David", 25));people.add(new Person("Eve", 28));people.add(new Person("Frank", 35));people.add(new Person("Grace", 40));people.add(new Person("Hannah", 22));people.add(new Person("Ian", 33));people.add(new Person("Jack", 29));people.add(new Person("Katherine", 62)); // 添加一个年龄大于60的人// 使用 groupingBy 按年龄范围分组// 使用 Stream 流和 groupingBy 方法进行分组Map<String, List<Person>> groupedByAgeRange = people.stream().collect(Collectors.groupingBy(person -> {int age = person.getAge();if (age > 18 && age < 25) {return "18-24";} else if (age >= 25 && age < 35) {return "25-34";} else if (age >= 35 && age < 60) {return "35-59";} else {return "60+";}}));// 打印分组结果groupedByAgeRange.forEach((ageRange, persons) -> {System.out.println("Age Range: " + ageRange);persons.forEach(System.out::println);System.out.println();});}
}
此外,还可以统计每个年龄段的有多少个人
Collectors.counting()是下游收集器,对分组之后的数据进行统计,更多的收集器类型可以参考https://docs.oracle.com/javase/8/docs/api/?java/lang/NullPointerException.html里面搜索Collectors类,里面的方法就是下游收集器
java">Map<String, Long> ageRangeCounts = people.stream().collect(Collectors.groupingBy(person -> {int age = person.getAge();if (age > 18 && age < 25) {return "18-24";} else if (age >= 25 && age < 35) {return "25-34";} else if (age >= 35 && age < 60) {return "35-59";} else {return "60+";}}, Collectors.counting())); // 使用 counting 方法统计每个分组的人数[^1^][^2^]// 打印每个年龄段的人数ageRangeCounts.forEach((ageRange, count) -> {System.out.println("Age Range: " + ageRange + ", Count: " + count);});
java">import java.util.*;
import java.util.stream.Collectors;// 定义一个Person类
class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return name + ": " + age;}
}public class StreamExample {public static void main(String[] args) {// 创建一个Person对象列表List<Person> people = Arrays.asList(new Person("Alice", 30),new Person("Bob", 25),new Person("Charlie", 30),new Person("David", 25));// 1. 过滤出年龄大于25的人List<Person> filteredPeople = people.stream().filter(person -> person.age > 25).collect(Collectors.toList());System.out.println("Filtered People: " + filteredPeople);// 2. 按年龄分组Map<Integer, List<Person>> peopleByAge = people.stream().collect(Collectors.groupingBy(person -> person.age));System.out.println("People Grouped by Age: " + peopleByAge);// 3. 按姓名排序并打印people.stream().sorted(Comparator.comparing(person -> person.name)).forEach(System.out::println);// 4. 计算平均年龄double averageAge = people.stream().mapToInt(person -> person.age).average().orElse(0.0);System.out.println("Average Age: " + averageAge);// 5. 去重并打印姓名people.stream().map(person -> person.name).distinct().forEach(System.out::println);// 6. 使用并行流过滤年龄大于25的人List<Person> parallelFilteredPeople = people.parallelStream().filter(person -> person.age > 25).collect(Collectors.toList());System.out.println("Parallel Filtered People: " + parallelFilteredPeople);}
}
代码说明:
过滤操作:使用filter方法过滤出年龄大于25的人。
分组操作:使用collect方法和Collectors.groupingBy按年龄分组。
排序操作:使用sorted方法按姓名排序。
计算平均值:使用mapToInt和average方法计算平均年龄。
去重操作:使用map和distinct方法提取并去重姓名。
并行流:使用parallelStream进行并行过滤操作。
输出示例:
假设运行上述代码,输出可能如下:
Filtered People: [Alice: 30, Charlie: 30]
People Grouped by Age: {25=[Bob: 25, David: 25], 30=[Alice: 30, Charlie: 30]}
Alice: 30
Bob: 25
Charlie: 30
David: 25
Average Age: 27.5
Alice
Bob
Charlie
David
Parallel Filtered People: [Alice: 30, Charlie: 30]
自己又写了一个过滤,排序,收集为列表的Stream操作,下面分开sort了是因为collect(Collectors.toList())返回了可变列表,直接toList是不可变列表,toList而非collect(Collectors.toList())会导致无法sort,
单独list.forEach是因为println出现了二义性调用,只能单独list.forEach(System.out::println);
java">package AAA;import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;public class Main5 {public static void main(String[] args) {// 创建一个Person对象列表List<Person> people = new ArrayList<>();// 手动插入100个Person对象people.add(new Person("Alice", 30));people.add(new Person("Bob", 25));people.add(new Person("Charlie", 30));people.add(new Person("David", 25));people.add(new Person("Eve", 28));people.add(new Person("Frank", 35));people.add(new Person("Grace", 40));people.add(new Person("Hannah", 22));people.add(new Person("Ian", 33));people.add(new Person("Jack", 29));// 继续添加更多的Person对象...// 打印生成的Person对象列表List<Person> list = people.stream().filter(p -> p.getAge() > 20 && p.getAge() < 30).collect(Collectors.toList());list.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));list.forEach(System.out::println);}
}