Stream流

一、简介

Stream流是Java 8中的一个新特性,它提供了一种处理集合和数组的方式。Stream流可以让我们以一种更加简洁、高效、可读性更强的方式来处理数据。Stream流可以用于过滤、映射、排序、聚合等操作,它可以让我们避免使用循环和条件语句来处理数据,从而让代码更加简洁易懂

二、流的分类

stream(顺序流)

顺序流是一种单线程的流,它按照数据流的顺序依次处理每个元素,每个元素的处理都必须等待上一个元素的处理完成才能开始

parallelStream(并行流)

并行流是一种多线程的流,它可以将数据分成多个部分并行处理,每个部分都可以在不同的线程中处理,从而提高处理效率

流的分类 方法 特点
顺序流 stream() 顺序流是一种单线程的流,它按照数据流的顺序依次处理每个元素,每个元素的处理都必须等待上一个元素的处理完成才能开始
并行流 parallelStream() 并行流是一种多线程的流,它可以将数据分成多个部分并行处理,每个部分都可以在不同的线程中处理,从而提高处理效率,但可能会影响数据的顺序和一致性。因此在使用并行流时需要注意线程安全和数据一致性等问题

三、常用方法

1. filter

filter(Predicate<T> predicate)通常用于过滤流中的元素,只保留符合条件的元素,例:

1
2
3
4
public static void main(String[] args) {
// 过滤大于5的数据到collect列表中
List<Integer> collect = Stream.of(1, 3, 5, 7, 9).filter(res -> res > 5).toList();
}

2. map && floatMap

map(Function<T, R> mapper)将流中的元素按照指定的方式进行映射,返回一个新的流

flatMap(Function<T, Stream<R>> mapper)将流中的元素按照指定的方式进行映射,然后将所有映射结果合并成一个流

1
2
3
4
public static void main(String[] args) {
// 过滤大于5的数据到collect列表中
List<Integer> collect = Stream.of(1, 3, 5, 7, 9).filter(res -> res > 5).toList();
}

3. limit

limit(long maxSize)通常用于截取流中的前maxSize个元素

1
2
3
4
public static void main(String[] args) {
// 截取前两条数据到collect列表中
List<Integer> collect = Stream.of(1, 3, 5, 7, 9).limit(2).toList();
}

4. skip

skip(long n)通常用于跳过流中的前n个元素

1
2
3
4
public static void main(String[] args) {
// 跳过前两条数据后保存到collect列表中
List<Integer> collect = Stream.of(1, 3, 5, 7, 9).skip(2).toList();
}

5. sorted

sorted():通常用于对流中的元素进行排序

1
2
3
4
public static void main(String[] args) {
// 正序排序后保存到collect列表中
List<Integer> collect = Stream.of(1, 3, 5, 7, 9).sorted().toList();
}

6. distinct

distinct():通常用于去重,去除流中重复的元素

1
2
3
4
public static void main(String[] args) {
// 去重后保存到collect列表中
List<Integer> collect = Stream.of(1, 3, 5, 5, 7, 9).distinct().toList();
}

7. forEach

forEach(Consumer<T> action):通常用于对流中的每个元素执行指定的操作

1
2
3
4
public static void main(String[] args) {
// 遍历元素并打印
Stream.of(1, 3, 5, 5, 7, 9).forEach(System.out::println);
}

8. reduce

reduce(T identity, BinaryOperator<T> accumulator):通常用于将流中的元素按照指定的方式进行累加,返回一个Optional对象

1
2
3
4
public static void main(String[] args) {
// 将元素累加打印总和
System.out.println(Stream.of(1, 2, 3, 4, 5, 6).reduce(0, Integer::sum));
}

9. collect

collect(Collector<T, A, R> collector):通常用于将流中的元素收集到一个集合中

1
2
3
4
public static void main(String[] args) {
// 将元素放入collect中
List<Integer> collect = Stream.of(1, 2, 3, 4, 5, 6).collect(Collectors.toList());
}

10. concat

concat(Stream<T> a, Stream<T> b) 通常用于合并a和b两个流为一个流

四、高级用法

1. 根据对象某字段去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
// 将元素放入collect中
List<Student> list = new ArrayList<>();
list.add(new Student(1, "张三", 13));
list.add(new Student(2, "李四", 14));
list.add(new Student(3, "张三", 15));

//根据用户名称进行数据去重
List<Student> distinctList = list.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList<Student>::new)
);
System.out.println(distinctList);
}