文章目录
1、过滤数据 filter()
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> numberFilter = numbers.stream()
.filter(n -> n % 2 == 0) // 过滤偶数
.collect(Collectors.toList()); // [2, 4]
2、转换元素 map()
List<String> words = Arrays.asList("apple", "banana");
List<Integer> lengths = words.stream()
.map(String::length) // 转换为单词长度
.collect(Collectors.toList()); // [5, 6]
3、排序 sorted()
List<String> list = Arrays.asList("a", "b", "c");
List<String> sortedList = list.stream()
.sorted() // 自然排序(字典序)
.collect(Collectors.toList());// [a, b, c]
3.1、自定义排序规则
List<Integer> nums = Arrays.asList(3, 1, 4);
List<Integer> customSorted = nums.stream()
.sorted((a, b) -> b - a) // 降序排序
.collect(Collectors.toList()); // [4, 3, 1]
4、去重 distinct()
List<Integer> num2 = Arrays.asList(1, 2, 2, 3);
List<Integer> unique = num2.stream()
.distinct() // 去重
.collect(Collectors.toList()); // [1, 2, 3]
5、限制元素数量 limit()
List<Integer> number2 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> firstThree = number2.stream()
.limit(3) // 取前3个元素
.collect(Collectors.toList()); // [1, 2, 3]
6、收集结果 collect()
6.1、收集为List
List<String> list3 = Arrays.asList("a", "b", "ac", "d", "a", "c");
List<String> filteredList = list3.stream()
.filter(s -> s.startsWith("a"))
.collect(Collectors.toList()); // 收集为List 过滤出以a开头的 [a, ac, a]
6.2、收集为Set
Set<String> set = list3.stream()
.collect(Collectors.toSet()); // 收集为Set 去重 [a, b, ac, c, d]
6.3、转为Map
Map<String, Integer> map = set.stream()
.collect(Collectors.toMap(s -> s, String::length)); // 转为Map 每个元素的长度 {a=1, ac=2, b=1, c=1, d=1}
6.4、基本用法(注意键冲突会抛异常)
实体类
@Data
public class Employee {
//部门
private String dept;
//姓名
private String name;
//薪水
private int salary;
public Employee(String dept, String name) {
this.dept = dept;
this.name = name;
}
public Employee(String dept, String name, int salary) {
this.dept = dept;
this.name = name;
this.salary = salary;
}
}
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("1", "张三", 6000));
employeeList.add(new Employee("2", "李四", 6000));
employeeList.add(new Employee("3", "王五", 6000));
Map<String, Integer> map2 = employeeList.stream().collect(
Collectors.toMap(
Employee::getDept, // 键的提取函数
Employee::getSalary // 值的提取函数
)
);
//{1=6000, 2=6000, 3=6000}
6.5、处理键冲突(例如,取后出现的值)
通过第三个参数(合并函数)解决键冲突:
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("1", "张三", 6000));
employeeList.add(new Employee("2", "李四", 6000));
employeeList.add(new Employee("3", "王五", 6000));
employeeList.add(new Employee("3", "赵六", 6000));
Map<String, String> map3 = employeeList.stream().collect(
Collectors.toMap(
Employee::getDept, // 键的提取函数
Employee::getName, // 值的提取函数
(oldVal, newVal) -> newVal // 解决冲突的函数(取新的value)
)
);
//{1=张三, 2=李四, 3=赵六}
6.6、指定 Map 实现类
/**
* 指定 Map 实现类
* 通过第四个参数自定义 Map 类型(如 LinkedHashMap 保持插入顺序):
*/
Map<String, String> idToName = employeeList.stream()
.collect(Collectors.toMap(
Employee::getDept,
Employee::getName,
(oldVal, newVal) -> newVal,
LinkedHashMap::new // 指定Map实现
));
//{1=张三, 2=李四, 3=赵六}
6.7、将对象自身作为值
/**
* 将对象自身作为值 (注意键冲突会抛异常)
* 使用 Function.identity() 直接引用元素作为值
*/
List<Employee> employeeList222 = new ArrayList<>();
employeeList222.add(new Employee("1", "张三", 6000));
employeeList222.add(new Employee("2", "李四", 6000));
employeeList222.add(new Employee("3", "王五", 6000));
Map<String, Employee> idToPerson = employeeList222.stream()
.collect(Collectors.toMap(
Employee::getDept,
Function.identity() // 值=对象本身
));
// {
// 1=Employee(dept=1, name=张三, salary=6000),
// 2=Employee(dept=2, name=李四, salary=6000),
// 3=Employee(dept=3, name=王五, salary=6000)
// }
6.8、统计总和
例如部门工资总和
List<Employee> employeeList333 = new ArrayList<>();
employeeList333.add(new Employee("1", "张三", 6000));
employeeList333.add(new Employee("2", "李四", 6000));
employeeList333.add(new Employee("3", "王五", 6000));
employeeList333.add(new Employee("1", "张三1", 7000));
employeeList333.add(new Employee("2", "李四1", 8000));
employeeList333.add(new Employee("3", "王五1", 9000));
Map<String, Integer> deptSalarySum = employeeList333.stream()
.collect(Collectors.toMap(
Employee::getDept,
Employee::getSalary,
Integer::sum // 合并时累加工资
));
//{1=13000, 2=14000, 3=15000}
6.9、字符串拼接
/** 字符串拼接 */
List<String> str = Arrays.asList("a", "b", "c");
String join1 = str.stream().collect(Collectors.joining()); //abc
String join2 = str.stream().collect(Collectors.joining(", ")); //a, b, c
String join3 = str.stream().collect(Collectors.joining(", ", "[", "]")); //[a, b, c]
7、遍历元素
List<String> list3 = Arrays.asList("a", "b", "ac", "d", "a", "c");
list3.stream().forEach(System.out::println); // 打印每个元素
8、匹配检查
/**
* 匹配检查: anyMatch() allMatch() noneMatch()
*/
List<String> list4 = Arrays.asList("a", "b", "c");
boolean hasA = list4.stream()
.anyMatch(s -> s.contains("a")); // 是否存在包含"a"的元素 true
List<Integer> numbers4 = Arrays.asList(1, 2, 3, 4, 5);
boolean allPositive = numbers4.stream()
.allMatch(n -> n > 0); // 是否所有元素都大于0 true
9、分组 Grouping By
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("1","张三", 5000));
employees.add(new Employee("1","李四", 5500));
employees.add(new Employee("2","王五", 6000));
employees.add(new Employee("2","赵六", 7000));
employees.add(new Employee("3","韩七", 5800));
employees.add(new Employee("4","魏八", 9000));
// 按属性分组(按照部门分组)
Map<String, List<Employee>> groupByDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDept));
// {
// 1=[Employee(dept=1, name=张三, salary=5000), Employee(dept=1, name=李四, salary=5500)],
// 2=[Employee(dept=2, name=王五, salary=6000), Employee(dept=2, name=赵六, salary=4000)],
// 3=[Employee(dept=3, name=韩七, salary=5800)],
// 4=[Employee(dept=4, name=魏八, salary=9000)]
// }
// 分组后对值进一步处理(如求数量:统计每个部门的人数)
Map<String, Long> countByDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDept, Collectors.counting()));
//{1=2, 2=2, 3=1, 4=1}
// 多级分组(嵌套分组) 先按照每个部门分组,然后按照薪水是否超过5000分组
Map<String, Map<Boolean, List<Employee>>> multiGroup = employees.stream()
.collect(Collectors.groupingBy(Employee::getDept,
Collectors.groupingBy(e -> e.getSalary() > 5000)));
// {
// 1={false=[Employee(dept=1, name=张三, salary=5000)], true=[Employee(dept=1, name=李四, salary=5500)]},
// 2={true=[Employee(dept=2, name=王五, salary=6000), Employee(dept=2, name=赵六, salary=7000)]},
// 3={true=[Employee(dept=3, name=韩七, salary=5800)]},
// 4={true=[Employee(dept=4, name=魏八, salary=9000)]}
// }
10、聚合操作 reduce()
List<Integer> numbers5 = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers5.stream()
.reduce((a, b) -> a + b); // 求和(返回Optional) Optional[15]
int total = numbers5.stream()
.reduce(0, Integer::sum); // 初始值为0的求和 15
11、统计
/**
* 统计: count() min() max()
*/
List<String> list5 = Arrays.asList("a", "b", "c");
long count = list5.stream().count(); // 元素总数 3
List<Integer> numbers6 = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> max = numbers6.stream().max(Integer::compare); // 最大值 Optional[5]
Optional<Integer> min = numbers6.stream().min(Integer::compare); // 最小值 Optional[1]
12、跳过元素 skip()
List<Integer> numbers7 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skipped = numbers7.stream()
.skip(2) // 跳过前2个元素
.collect(Collectors.toList()); //[3, 4, 5]