1.概述
在 Java 中,List.stream()是将一个List(列表)转换为一个Stream(流)的操作。Stream是 Java 8 引入的一个强大的新特性,用于处理集合(如List)中的元素。它提供了一种函数式编程的方式来对集合中的元素进行操作,比如过滤、映射、排序等。
过滤操作(filter)
功能:用于筛选出符合特定条件的元素。
示例:假设有一个List存储了一些水果名称,我们想要筛选出以字母 “A” 开头的水果。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Apricot");
List<String> filteredFruits = fruits.stream()
.filter(fruit -> fruit.startsWith("A"))
.toList();
System.out.println(filteredFruits);
}
}
在这个例子中,filter(fruit -> fruit.startsWith(“A”))会对fruits列表中的每个元素应用startsWith(“A”)这个条件判断。只有满足条件的元素(这里是 “Apple” 和 “Apricot”)才会被保留下来,最后通过toList()收集到新的List中并打印出来。
2、映射操作(map)
功能:将一个元素转换为另一个元素。通常用于对集合中的元素进行类型转换或者基于元素的值进行计算得到新的值。
示例:假设有一个List存储了一些整数,我们想要将每个整数平方后得到一个新的列表。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
List<Integer> squaredNumbers = numbers.stream()
.map(n -> n * n)
.toList();
System.out.println(squaredNumbers);
}
}
这里map(n -> n * n)会将numbers列表中的每个整数n进行平方操作,然后将得到的新元素收集到squaredNumbers列表中并打印。
3、排序操作(sorted)
功能:对集合中的元素进行排序。可以按照元素的自然顺序(如果元素实现了Comparable接口)或者通过自定义的比较器进行排序。
示例 1:按照自然顺序排序:假设有一个List,我们想要对其进行升序排序。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(3);
numbers.add(1);
numbers.add(2);
List<Integer> sortedNumbers = numbers.stream()
.sorted()
.toList();
System.out.println(sortedNumbers);
}
}
在这个例子中,sorted()会按照整数的自然升序顺序对numbers列表中的元素进行排序,结果是[1, 2, 3]。
示例 2:按照自定义比较器排序:假设有一个List存储了一些人名,我们想要按照人名的长度进行升序排序。
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
List<String> sortedNames = names.stream()
.sorted(Comparator.comparingInt(String::length))
.toList();
System.out.println(sortedNames);
}
}
这里Comparator.comparingInt(String::length)创建了一个比较器,用于比较字符串的长度。sorted操作会根据这个比较器对names列表中的元素进行排序,结果是[Bob, Alice, Charlie]。
4、去重操作(distinct)
功能:去除集合中的重复元素。它会根据元素的equals和hashCode方法来判断元素是否相同。
示例:假设有一个List包含了一些重复的整数,我们想要去除重复的元素。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(1);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.toList();
System.out.println(distinctNumbers);
}
}
在这个例子中,distinct()会去除numbers列表中的重复元素,结果是[1, 2]。
5、归约操作(reduce)
功能:将集合中的元素通过一个二元操作符(如求和、求乘积等)组合成一个单一的值。
示例 1:求和操作:假设有一个List,我们想要计算所有元素的和。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
Integer sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
System.out.println(sum);
}
}
这里reduce(0, (a, b) -> a + b)的第一个参数0是初始值(也称为累加器的初始值),第二个参数(a, b) -> a + b是一个二元操作符,表示将当前的累加值a和流中的下一个元素b相加。在这个例子中,最终的结果是6。
示例 2:求乘积操作:假设有一个List,我们想要计算所有元素的乘积。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
Integer product = numbers.stream()
.reduce(1, (a, b) -> a * b);
System.out.println(product);
}
}
这个例子中,初始值为1,二元操作符是(a, b) -> a * b,用于计算元素的乘积,最终结果是6。
6、收集操作(collect)
功能:将流中的元素收集到一个特定的数据结构中,如List、Set、Map等。最常用的是Collectors工具类提供的方法。
示例 1:收集到List中:前面的例子中我们已经使用过toList()来收集元素到List中,它实际上是collect(Collectors.toList())的简化形式。
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
List<Integer> collectedList = numbers.stream()
.collect(Collectors.toList());
System.out.println(collectedList);
}
}
示例 2:收集到Set中(用于去重):如果想要收集元素到Set中,以利用Set的不重复性。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(1);
Set<Integer> collectedSet = numbers.stream()
.collect(Collectors.toSet());
System.out.println(collectedSet);
}
}
这里collect(Collectors.toSet())会将numbers流中的元素收集到一个Set中,由于Set的特性,重复的元素会被自动去除,结果是{1, 2}。
示例 3:收集到Map中:假设有一个List存储了一些学生的姓名和成绩(格式为 “姓名:成绩”),我们想要将其收集到一个Map中,其中姓名为键,成绩为值。
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> studentScores = new ArrayList<>();
studentScores.add("Alice:80");
studentScores.add("Bob:90");
studentScores.add("Charlie:70");
Map<String, Integer> scoreMap = studentScores.stream()
.collect(Collectors.toMap(
s -> s.split(":")[0],
s -> Integer.parseInt(s.split(":")[1])
));
System.out.println(scoreMap);
}
}
在这个例子中,Collectors.toMap方法的第一个参数s -> s.split(“:”)[0]用于从字符串中提取姓名作为键,第二个参数s -> Integer.parseInt(s.split(“:”)[1])用于从字符串中提取成绩并转换为整数作为值,最终得到一个Map<String, Integer>,结果可能是{Alice=80, Bob=90, Charlie=70}。
上文为学习时豆包给与的实例,下文为学习后根据自身实际业务所生成
List<Map<String, List<vo>>> collect2 = voList
.stream()
//根据实体类名称进行分类
.collect(Collectors.groupingBy(vo::getName))
.values()
.stream()
.map(entry -> entry
//映射的值为value的每个list,在生成流
.stream()
//再根据年龄
.collect(Collectors.groupingBy(vo::getAge)))
//过滤掉空的map
.filter(NullAndEmptyUtil::isNotEmptyMap).collect(Collectors.toList());
//因为是双层分组 要循环两次 才能拿到最里面的值
for (Map<String, List<vo>> list : collect2) {
for (Map.Entry<String, List<vo>> map : list.entrySet()) {
if (NullAndEmptyUtil.isNotNullList(stringListEntry.getValue())) {
//在进行排序下
stringListEntry.setValue(stringListEntry.getValue().stream().sorted(Comparator.comparing(vo::getcreateTime)).collect(Collectors.toList()));
}
System.out.print(stringListEntry.getValue().get(0).getDeptName());
}
}