常用Stream流

简介: 常用Stream流

常用Stream流

6.2 使用建议

一:什么是Stream流

Stream流是Java 8中引入的一个新特性,它是一个功能强大的工具,可以用来处理集合(Collection)和数组(Array)中的元素。Stream流可以看作是一种迭代器,它允许对集合中的元素进行一系列的处理操作,比如筛选、映射、排序、聚合等。

Stream流有以下几个特点:


Stream流是一种惰性求值的操作方式,即在使用时才进行处理,可以避免不必要的计算。

Stream流可以对集合或数组进行一系列的中间操作,如过滤、映射、排序等,同时也支持终止操作,如归约、收集等。

Stream流可以处理无限流,也可以处理有限流。

通过使用Stream流,可以简化代码,提高代码的可读性和可维护性。同时,由于Stream流的特性,可以更好地利用现代CPU的多核心能力,提高程序的运行效率。


二:Stream的作用

Stream流有以下几个作用:


简化集合或数组的处理:Stream流提供了一系列的中间操作和终止操作,可以方便地对集合或数组进行筛选、映射、排序、聚合等操作,大大简化了集合或数组的处理。

提高程序的效率:Stream流可以利用现代CPU的多核心能力,同时也避免了不必要的计算,提高了程序的运行效率。

支持无限流处理:Stream流支持无限流处理,可以对无限的数据集进行处理,同时也支持有限流处理。

增强代码的可读性和可维护性:Stream流的语法简单明了,可以很容易地理解代码的逻辑,同时也使得代码更易于维护。

三: Stream流简单示例

3.1 数据源

        List<User> list = Arrays.asList(
                new User("小明", 20, 3000),
                new User("小红", 20, 2000),
                new User("小亮", 22, 5000)
        );

3.2 数据处理

        // stream 流
        Predicate<User> predicate1 = user -> user.getAge() < 21;
        Predicate<User> predicate2 = user -> user.getAge() < 2000;
        List<User> collect = list.stream()
                .filter(predicate1.or(predicate2))
                .collect(Collectors.toList());
        System.out.println(collect);

3.3 filter 过滤

        // filter 过滤
        List<String> testList = Arrays.asList("Hello", "World", "Java");
        testList.stream()
                .filter(str -> str.length() >= 5)
                .forEach(str -> System.out.println(str));

3.4 limit 取前几

        // limit
        testList.stream()
                .limit(2)
                .forEach(str -> System.out.println(str));

3.5 sorted 排序

        // sorted 排序
        List<Integer> integerList = Arrays.asList(1, 6, 5, 4, 2, 3);
        integerList.stream()
                .sorted()//正序
                .sorted(Comparator.reverseOrder())//反序
                .forEach(num -> System.out.println(num));

3.6 max、min、count

        // max、min、count
        System.out.println("最大的数:" + integerList.stream().max(Integer::compareTo).get());
        System.out.println("最小的数:" + integerList.stream().min(Integer::compareTo).get());
        System.out.println("集合长度:" + integerList.stream().count());

3.7 map 对集合中的元素进行特定的操作

        // map 对集合中的元素进行特定的操作
        integerList.stream()
                .map(num -> num + 10)
                .forEach(num -> System.out.println(num));

3.8 reduce 将所有的元素按照传入的逻辑进行处理,并且会把结果合并成一个值进行返回

        // reduce 将所有的元素按照传入的逻辑进行处理,并且会把结果合并成一个值进行返回
        System.out.println("集合中的元素求和为:" + integerList.stream().reduce((sum, num) -> sum + num).get());

3.9 collection 基于目标集合生成新的数组

        // collection 基于目标集合生成新的数组
        List<Integer> collectList = integerList.stream()
                .filter(num -> num % 2 == 0)
                .collect(Collectors.toList());
        System.out.println("偶数集合:" + collectList);

四:使用Stream流对集合进行分页

// 通过流处理进行分页
List<String> subList = denyList.stream()
    .skip((pageNo-1)*pageSize) // 跳过(第pageNo页-1)*每页多少条 例如:第一页就是跳过0条,第二页跳过1*每页的条数...
    .limit(pageSize)// 取pageSize条数据
    .collect(Collectors.toList());// 将过滤的数据输出成集合

五:对集合中实体中某个字段进行去重

// 使用
List<TopicReplyRecord> filterDistinctList = notUserNameCommentsList.stream()
                    .filter(distinctByKey(TopicReplyRecord::getReply_record_id))
                    .collect(Collectors.toList());
    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

六:Stream流性能分析与使用建议

6.1 性能分析

1.在少数据量的处理场景中(size <= 1000)

stream 的处理效率是不如传统的 iterator 外部迭代器处理速度快的,但是实际上这些处理任务本身运行时间都低于毫秒,这点效率的差距对普通业务几乎没有影响,反而 stream 可以使得代码更加简洁;

2.在大量数据(size > 10000)

stream 的处理效率会高于 iterator,特别是使用了并行流,在 cpu 恰好将线程分配到多个核心的条件下(当然 parallel stream 底层使用的是 JVM 的 ForkJoinPool,这东西分配线程本身就很玄学),可以达到一个很高的运行效率,然而实际普通业务一般不会有需要迭代高于 10000 次的计算;


Parallel Stream (并行流)

Parallel Stream 受引 CPU 环境影响很大,当没分配到多个 cpu 核心时,加上引用 forkJoinPool 的开销,运行效率可能还不如普通的 Stream;


6.2 使用建议

1.简单的迭代逻辑,可以直接使用 iterator,对于有多步处理的迭代逻辑,可以使用 stream,损失一点几乎没有的效率,换来代码的高可读性是值得的;

2.单核 cpu 环境,不推荐使用 parallel stream,在多核 cpu 且有大数据量的条件下,推荐使用 paralle stream;

stream 中含有装箱类型,在进行中间操作之前,最好转成对应的数值流,减少由于频繁的拆箱、装箱造成的性能损失。


目录
相关文章
|
2月前
|
存储 JavaScript 网络协议
Stream
【10月更文挑战第22天】
30 1
|
7月前
|
存储 Java API
Stream流
Stream流
66 1
|
3月前
|
Java 数据处理
Stream流的简单使用
这篇文章介绍了Java中Stream流的基本概念和使用方法。文章解释了Stream流的三类方法:获取流、中间方法和终结方法。详细讨论了如何生成Stream流,包括从Collection体系集合、Map体系集合、数组和同种数据类型的多个数据中生成流。接着,介绍了Stream流的中间操作方法,如`filter`、`limit`、`skip`、`concat`和`distinct`。文章还讨论了Stream流的终结方法,如`forEach`和`count`,以及收集方法,如`collect`。最后,通过几个例子演示了如何使用Stream流进行数据处理和收集操作。
|
7月前
|
Java 容器
Stream 流常见基本操作
Stream 流常见基本操作
|
6月前
|
API
Stream流知识
Stream流知识
32 0
|
6月前
|
存储 Java API
Java——Stream流(1/2):Stream流入门、Stream流的创建(认识Stream、体验Stream流、Stream流的使用步骤、获取Stream流的方法)
Java——Stream流(1/2):Stream流入门、Stream流的创建(认识Stream、体验Stream流、Stream流的使用步骤、获取Stream流的方法)
92 0
|
Java
stream流操作
stream流操作
78 0
|
7月前
|
Java
Stream流教程
Stream流教程
72 0
|
Java
stream流分组
stream流分组
92 0