笔者日常: Stream知识点真的是…太多了!!!
声明: 由于Stream知识极多,所以本人将其分为两个部分进行学习。
Stream(上)主要学习的内容有:

Stream(下)主要学习的内容有:

Stream学习(上):
-
Stream实例的(常用)获取方法:
- 串行流:
- Collection.stream()
- Stream.of(T… values)
- stream.sequential()
- Arrays.stream()
- ……
- 并行流:
- Collection.parallelStream()
- stream.parallel()
- …
- 相关说明:
- 串行流由单线程进行处理执行, 并行流由多线程进行处理执行。
- 在多核的情况下,并行流效率更高。
- 推荐使用Stream,而不使用显示迭代(如: for循环等)。
- 显示循环、串行流、并行流的性能比较可参考here。
- 串行流、并行流的只是介绍可参考here。
- 在使用并行流时,如果只是用其来处理集合A本身的话,是不会有线程问题的(其内部会自己处理好);如果在使用并行流的时候,涉及到了其他变量B,那么可能出现线程不安全的情况。 如:
listA.parallelStream().map(x -> {listB.add(x); return x;}).forEachOrdered(System.out::print)中,listA的并行流中 进行x -> {listB.add(x); return x;}操作,即:多线程中调用listB的add方法,如果listB是线程不安全的,那么就可能出现问题。
- 示例:
/** * 获取串行流: * Collection.stream(): 获取串行Stream * Stream.of(T... values): 获取串行Stream * stream.sequential(): 获取串行Stream * Arrays.stream() * …… * * 获取并行流: * Collection.parallelStream(): 获取并行Stream * stream.parallel(): 获取并行Stream * …… * * 注:获取Stream实例的方式方式比较多,这里只示例了最基本的几种方式。 * * 相关说明: * 1、串行流由单线程进行处理执行, 并行流由多线程进行处理执行。 * 2、在多核的情况下,并行流效率更高。 * 3、推荐使用Stream,而不使用显示迭代(如: for循环等)。 * 4、显示循环、串行流、并行流的性能比较可参考<linked>https://blog.csdn.net/java1856905/article/details/88640557</linked> * 5、串行流、并行流的只是介绍可参考<linked>https://www.jianshu.com/p/19ffb2c9438a</linked> * 6、在使用并行流时,如果只是用其来处理集合A本身的话,是不会有线程问题的(其内部会自己处理好);如果在使用并 * 行流的时候,涉及到了其他变量B,那么可能出现线程不安全的情况。 如: * listA.parallelStream() * .map(x -> {listB.add(x); return x;}) * .forEachOrdered(x -> System.out.print(x) * 中,listA的并行流中 进行x -> {listB.add(x); return x;}操作, * 即: 多线程中调用listB的add方法,如果listB是线程不安全的,那么就可能出现问题。 */ @Test public void test1() { // 数据准备 List<Staff> tmpList = Lists.newArrayList( Staff.builder().name("张三").age(18).staffNo("NO1").build(), Staff.builder().name("李四").age(25).staffNo("NO2").build(), Staff.builder().name("王五").age(40).staffNo("NO3").build() ); /// 获取串行Stream // 常用方式一 Stream<Staff> stream = tmpList.stream(); // 常用方式二 // 这样: // Stream<Staff> stream = Stream.of(a, b, c); // 或这样: // Staff[] tmpArray = {a, b, c}; // Stream<Staff> stream = Stream.of(tmpArray); // 或这样: // Arrays.stream() /// 获取并行Stream // Stream<Staff> stream = tmpList.parallelStream(); // Stream.of(a, b, c).parallel(); }
- 串行流:
-
boolean allMatch(Predicate<? super T> predicate) : 是否【所有元素都满足Predicate】。
-
boolean allMatch(Predicate<? super T> predicate) :是否【存在元素满足Predicate】。
-
boolean noneMatch(Predicate<? super T> predicate) :是否【所有元素都不满足Predicate】。
- 示例:
/** * boolean allMatch: 是否【所有元素都满足Predicate】 * boolean anyMatch: 是否【存在元素满足Predicate】 * boolean noneMatch: 是否【所有元素都不满足Predicate】 */ @Test public void test2() { // 数据准备 List<Staff> tmpList = Lists.newArrayList( Staff.builder().name("张三").age(18).staffNo("NO1").build(), Staff.builder().name("李四").age(25).staffNo("NO2").build(), Staff.builder().name("王五").age(40).staffNo("NO3").build() ); Stream<Staff> stream = tmpList.stream(); // -> Stream.allMatch 测试 // Predicate<Staff> predicateOne = x -> x.getAge() >= 18; // 控制台输出true。 即:stream中的所有Staff均满足predicateOne. // System.out.println(stream.allMatch(predicateOne)); // -> Stream.anyMatch 测试 // Predicate<Staff> predicateTwo = x -> x.getName() != null && x.getName().contains("王"); // 控制台输出true。 即:stream中存在Staff满足 predicateTwo. // System.out.println(stream.anyMatch(predicateTwo)); // -> Stream.noneMatch 测试 Predicate<Staff> predicateThree = x -> "JustryDeng".equals(x.getName()); // 控制台输出true。 即:stream中不存在任何Staff满足 predicateThree. System.out.println(stream.noneMatch(predicateThree)); }
- 示例:
-
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):创建一个Stream<T>,其元素是:在第一个流的所有元素后再接上第二个流的所有元素。
- 示例:
/** * static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b): 创建一个String<T>,其元 * 素是:在第一个流的所有元素后再接上第二个流的所有元素 */ @Test public void test3() { // 基础数据准备 Staff a = Staff.builder().name("张三").age(18).staffNo("NO1").build(); Staff c = Staff.builder().name("王五").age(40).staffNo("NO3").build(); Stream<Staff> streamA = Stream.of(a, c); Staff b = Staff.builder().name("李四").age(25).staffNo("NO2").build(); Stream<Staff> streamB = Stream.of(b); // 按前后顺醋,"拼接"两个流 Stream<Staff> stream = Stream.concat(streamA, streamB); // 输出:[Staff(name=张三, age=18, staffNo=NO1), Staff(name=王五, age=40, staffNo=NO3), Staff(name=李四, age=25, staffNo=NO2)] System.out.println(Arrays.deepToString(stream.toArray())); }
- 示例:
-
long count():返回此Stream中的元素数量。
- 示例:
/** * long count: 返回此Stream中的元素数量 */ @Test public void test4() { // 数据准备 List<Staff> tmpList = Lists.newArrayList( Staff.builder().name("张三").age(18).staffNo("NO1").build(), Staff.builder().name("李四").age(25).staffNo("NO2").build(), Staff.builder().name("王五").age(40).staffNo("NO3").build() ); Stream<Staff> stream = tmpList.stream(); // 输出: 3 System.out.println(stream.count()); }
- 示例:
-
void forEach(Consumer<? super T> action):遍历元素进行消费。
-
void forEachOrdered(Consumer<? super T> action):有序遍历元素进行消费。
- 注:如果是串行流,使用forEach和使用forEachOrdered都能顺序消费。如果是并行流,使用forEachOrdered能保证有序消费,而forEach不能保证。
- 示例:
/** * void forEach(Consumer<? super T> action): 遍历元素进行消费 * * void forEachOrdered(Consumer<? super T> action): 有序遍历元素进行消费 * * 注:如果是串行流,使用forEach和使用forEachOrdered都能顺序消费。 * 如果是并行流,使用forEachOrdered能保证有序消费,而forEach不能保证。 */ @Test public void test6() { // 数据准备 List<Integer> tmpList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9); // 串行流 forEach Stream<Integer> sequentialStreamOne = tmpList.stream(); // 输出: 1 2 3 4 5 6 7 8 9 sequentialStreamOne.forEach(x -> System.out.print(x + "\t")); System.out.print("\n"); // 串行流 forEachOrdered Stream<Integer> sequentialStreamTwo = tmpList.stream(); // 输出: 1 2 3 4 5 6 7 8 9 sequentialStreamTwo.forEachOrdered(x -> System.out.print(x + "\t")); System.out.print("\n"); // 并行流 forEach Stream<Integer> parallelStreamOne = tmpList.parallelStream(); // 输出: 6 5 7 8 9 2 1 4 3 parallelStreamOne.forEach(x -> System.out.print(x + "\t")); System.out.print("\n"); // 并行流 forEachOrdered Stream<Integer> parallelStreamTwo = tmpList.parallelStream(); // 输出: 1 2 3 4 5 6 7 8 9 parallelStreamTwo.forEachOrdered(x -> System.out.print(x + "\t")); }
-
Stream<T> distinct():根据equals方法去重。
- 示例:
/** * Stream<T> distinct: 根据equals方法去重。 */ @Test @SuppressWarnings("all") public void test7() { String a = "JustryDeng"; String b = new String("JustryDeng"); String c = "邓帅"; String d = new String("邓帅"); // 数据准备 List<String> tmpList = Lists.newArrayList(a,b, c,d); Stream<String> stream = tmpList.parallelStream(); // 去重 stream = stream.distinct(); stream.forEachOrdered(System.out::println); }
- 示例:
-
Stream<T> filter(Predicate<? super T> predicate):筛选出(只留下)满足predicate的元素。
- 示例:
/** * Stream<T> filter(Predicate<? super T> predicate): 筛选出(只留下)满足predicate的元素。 */ @Test public void test8() { // 数据准备 List<Integer> tmpList = Lists.newArrayList(1, 2,
- 示例:

本文深入讲解Java Stream API的使用,涵盖串行流与并行流的获取方法、常见操作如filter、map、reduce等,以及排序、去重、归并等高级应用。通过示例代码演示如何高效利用Stream处理集合数据。

2万+

被折叠的 条评论
为什么被折叠?



