java8新特性(四)_Stream详解

简介: 之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行使用Stream简单介绍定义A sequence of elements supporting sequential and parallel aggregate operations.支持顺序并行聚合操作的元素序列看看大神们怎么解读的大家可以把Stream当成一个高级版本的Iterator。

之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行使用

Stream简单介绍

定义

  • A sequence of elements supporting sequential and parallel aggregate operations.

  • 支持顺序并行聚合操作的元素序列

看看大神们怎么解读的

大家可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,具体这些操作如何应用到每个元素上,就给Stream就好了

简单demo

写一个过滤null的简单功能
    public static void main(String[] args) {

        List arrys = Arrays.asList(1, null, 3, 4);
        arrys.forEach(System.out::print);
        System.out.println();
        arrys = (List) arrys.stream()
                .filter(num -> num != null)
                .collect(Collectors.toList());
        arrys.forEach(System.out::print);

    }

执行结果

1null34
134
解析代码


1、 创建Stream;
2、 转换Stream(处理数据),每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换);
3、 对Stream进行聚合(Reduce)操作,获取想要的结果;

创建Stream

最常用的创建Stream有两种途径:

  • 通过Stream接口的静态工厂方法
  • 通过Collection接口的默认方法–stream(),把一个Collection对象转换成Stream(之前写的文章对于map的处理就是基于这个)
// 1. Individual values
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays
String [] strArray = new String[] {"a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3. Collections(实际工作中经常用到)
List<String> list = Arrays.asList(strArray);
stream = list.stream();

转换Stream方法详解

这里其实是大家常用到的,着重讲解这里,这里的图片来自并发编程网,不得不佩服,程序写的好,画图也比我画的好

distinct

distinct: 对于Stream中包含的元素进行去重操作(去重逻辑依赖元素的equals方法),新生成的Stream中没有重复的元素;

示意图

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .distinct()
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
java---erlang---lua---

filter

filter: 对于Stream中包含的元素使用给定的过滤函数进行过滤操作,新生成的Stream只包含符合条件的元素;

示意图

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .filter(e -> e.length() > 7)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
erlang---

map

map:它的作用就是把 input Stream 的每一个元素,映射成 output Stream 的另外一个元素。

示意图

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
JAVA---JAVA---ERLANG---LUA---LUA---

limit

limit: 对一个Stream进行截断操作,获取其前N个元素,如果原Stream中包含的元素个数小于N,那就获取其所有的元素;

示意图

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .limit(3)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
java---java---erlang---

skip

skip:返回一个丢弃原Stream的前N个元素后剩下元素组成的新Stream,如果原Stream中包含的元素个数小于N,那么返回空Stream;

示意图

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        list = list.stream()
                .skip(3)
                .collect(Collectors.toList());
        list.forEach(System.out::print);

    }

结果

java---java---erlang---lua---lua---
lua---lua---

findFirst

findFirst:它总是返回 Stream 的第一个元素,或者空。这里比较重点的是它的返回值类型:Optional

示意图

代码演示
    public static void main(String[] args) {

        List<String> list = Arrays.asList("java---", "java---", "erlang---", "lua---", "lua---");
        list.forEach(System.out::print);
        System.out.println();
        Optional<String> first = list.stream()
                .findFirst();

        System.out.println(first.get());

    }

结果

java---java---erlang---lua---lua---
java---

总结

当然,还有很多方法,这里不一一介绍,现实工作中使用常常结合起来

比如这段代码就是之前文章 过滤map 中 null值和空串的例子

public static Map<String, Object> parseMapForFilterByOptional(Map<String, Object> map) {

        return Optional.ofNullable(map).map(
                (v) -> {
                    Map params = v.entrySet().stream()
                            .filter((e) -> checkValue(e.getValue()))
                            .collect(Collectors.toMap(
                                    (e) -> (String) e.getKey(),
                                    (e) -> e.getValue()
                            ));

                    return params;
                }
        ).orElse(null);
    }

总之,Stream 的特性可以归纳为:

不是数据结构

  • 它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。
  • 它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。
  • 所有 Stream 的操作必须以 lambda 表达式为参数

参考文章
-[1.]https://ifeve.com/stream/
-[2.]https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/

学习不是要么0分,要么100分的。80分是收获;60分是收获;20分也是收获。有收获最重要。但是因为着眼于自己的不完美,最终放弃了,那就是彻底的0分了。
相关文章
|
17天前
|
存储 安全 Java
Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
【10月更文挑战第17天】Java Map新玩法:探索HashMap和TreeMap的高级特性,让你的代码更强大!
43 2
|
19天前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
33 3
|
19天前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
30 2
|
21天前
|
存储 算法 Java
Java Set因其“无重复”特性在集合框架中独树一帜
【10月更文挑战第14天】Java Set因其“无重复”特性在集合框架中独树一帜。本文深入解析Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定的数据结构(哈希表、红黑树)确保元素唯一性,并提供最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的`hashCode()`与`equals()`方法。
27 3
|
25天前
|
安全 Java API
Java 17新特性让你的代码起飞!
【10月更文挑战第4天】自Java 8发布以来,Java语言经历了多次重大更新,每一次都引入了令人兴奋的新特性,极大地提升了开发效率和代码质量。本文将带你从Java 8一路走到Java 17,探索那些能让你的代码起飞的关键特性。
69 1
|
11天前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。
|
1月前
|
Java 流计算
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
35 1
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
|
15天前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
36 3
|
15天前
|
存储 安全 Java
Java Map新玩法:深入探讨HashMap和TreeMap的高级特性
【10月更文挑战第19天】Java Map新玩法:深入探讨HashMap和TreeMap的高级特性,包括初始容量与加载因子的优化、高效的遍历方法、线程安全性处理以及TreeMap的自然排序、自定义排序、范围查询等功能,助你提升代码性能与灵活性。
23 2
|
22天前
|
Java 开发者
在Java的集合世界里,Set以其独特的特性脱颖而出,它通过“哈希魔法”和“红黑树防御”两大绝技
【10月更文挑战第13天】在Java的集合世界里,Set以其独特的特性脱颖而出。它通过“哈希魔法”和“红黑树防御”两大绝技,有效抵御重复元素的侵扰,确保集合的纯洁性和有序性。无论是“人海战术”还是“偷梁换柱”,Set都能从容应对,成为开发者手中不可或缺的利器。
30 6