IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java8 stream使用教程 -> 正文阅读

[Java知识库]java8 stream使用教程

简介

Java 8 API添加了一个支持对元素流进行函数式操作的类 Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选排序聚合等。

元素流在管道中经过 中间操作(intermediate operation) 的处理,最后由 终端操作(terminal operation) 得到前面处理的结果。

大多stream操作接受某种形式的lambda表达式作为参数,通过方法接口的形式指定操作的具体行为,这些方法接口的行为基本上都是无干扰(non-interfering)和无状态(stateless)

  • 无干扰(non-interfering):该方法不修改stream的底层数据源。
  • 无状态(stateless):操作的执行是独立的,没有lambda表达式在执行中依赖可能发生变化的外部变量或状态。

示例源代码

stream的创建

  • 从一个 Collection 的 stream() 和 parallelStream() 方法;
  • 从一个数组通过 Arrays.stream(Object[]);
  • 来自流类上的静态工厂方法,例如 Stream.of(Object[]), IntStream.range(int, int) 或Stream.iterate(Object, UnaryOperator);
  • 文件的行可以从 BufferedReader.lines() 获得;
  • 文件路径流可以从 Files 中的方法获得;
  • 可以从 Random.ints() 获得随机数流;
  • JDK 中的许多其他流承载方法,包括 BitSet.stream()、Pattern.splitAsStream(java.lang.CharSequence) 和 JarFile.stream()。
private static void createStream() {
        List<String> list = new ArrayList<String>() {//这个大括号 就相当于我们  new 接口
            {//这个大括号 就是 构造代码块 会在构造函数前 调用
                this.add("hi");
                this.add("sorry");
                this.add("hello");
                this.add("word");
            }
        };
        // 从一个 Collection 的 stream() 和 parallelStream() 方法
        list.stream().map(it -> it + " dd").forEach(System.out::println);
        // 并发不保证执行顺序
        list.parallelStream().map(it -> it + " dd").forEach(System.out::println);

        String[] array = new String[]{
                "one", "two", "three"
        };
        // 从一个数组通过 Arrays.stream(Object[])
        Arrays.stream(array).map(it -> it + " dd").forEach(System.out::println);

        // 来自流类上的静态工厂方法
        IntStream.range(1, 5).forEach(System.out::println);
        // 无限流
        Stream.iterate(1, s -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return s + 1;
        }).forEach(System.out::println);

        // 文件的行可以从 BufferedReader.lines() 获得
        try {
            new BufferedReader(new FileReader("./test.txt")).lines().forEach(System.out::println);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        // 从 Random.ints() 获得随机数流
        new Random().ints(3, 1, 20).forEach(System.out::println);
    }

简单使用

中间操作

  • 过滤: filter(T -> boolean) (非干扰、无状态)
  • 类型转换: map(T -> R) 将流中的每一个元素 T 映射为 R (非干扰、无状态)
  • flatMap(T -> Stream) 将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流
  • distinct() 将流中重复的元素去除,去重 (非干扰、有状态)
  • 根据字段排序 sorted() / sorted((T, T) -> int) (非干扰、有状态)
  • peek(T -> void)返回由该流的元素组成的流, 这个方法存在主要是为了支持调试,你想要的地方查看流经管道中某个点的元素
  • 返回前 n 个元素 limit(long n) (短路、有状态)
  • 跳过前 n 个元素 skip(long n) (有状态)
    private static void intermediateOperation() {
        String[] array = new String[]{
                "one, two", "four, five", "two, three", "three, four", "one, two", "six", "ten", "five", "three"
        };

        Arrays.stream(array)
                .filter(s -> s.startsWith("t"))
                .forEach(System.out::println);

        Arrays.stream(array)
                .map(s -> s.split(","))
                .flatMap(Arrays::stream)
                .peek(s -> System.out.println("flatMap -> " + s))
                .map(String::trim)
                .distinct()
                .sorted((String::compareTo))
                .limit(3)
                .skip(1)
                .forEach(System.out::println);
    }

终端操作

  • 遍历操作 forEach(e -> { … }) / forEachOrdered(e -> { … })
  • toArray() 返回一个包含此流元素的数组。
  • reduce((T, T) -> T)reduce(T, (T, T) -> T)reduce(R, (R, T) -> R, (R, R) -> R) 用于组合流中的元素,如求和,求积,求最大值等
  • collect() 收集方法,我们很常用的是 collect(toList()),当然还有 collect(toSet()) 等,参数是一个收集器接口
  • min()max()count() 最小值、最大值、流中元素数量
  • anyMatch(T -> boolean) 流中是否有一个元素匹配给定的 T -> boolean 条件
  • allMatch(T -> boolean) 流中是否所有元素都匹配给定的 T -> boolean 条件
  • noneMatch(T -> boolean) 流中是否没有元素匹配给定的 T -> boolean 条件
  • findAny():找到其中一个元素, 使用 stream() 时找到的是第一个元素;parallelStream() 并行时找到的是其中一个元素; findFirst():找到第一个元素; 值得注意的是,这两个方法返回的是一个 Optional 对象,它是一个容器类,能代表一个值存在或不存在
    private static void terminalOperation() {
        int[] array = new int[]{
                1, 2, 3, 4, 5, 2, 1, 3, 7
        };
        // reduce((T, T) -> T) 不接受任何起始值,但因为没有初始值,需要考虑结果可能不存在的情况,因此返回的是 Optional 类型
        OptionalInt res = Arrays.stream(array).reduce(Integer::sum);
        // reduce(T, (T, T) -> T) reduce 第一个参数 0 代表起始值为 0
        int res1 = Arrays.stream(array).reduce(0, Integer::sum);

        List<Widget> widgetList = Widget.genRandomWidgets(10);
        // reduce(R, (R, T) -> R, (R, R) -> R)
        int sumOfWeights = widgetList.stream().reduce(0, (sum, b) -> sum + b.getWeight(), Integer::sum);
        System.out.println("res = " + res + " res1 = " + res1 + " sumOfWeights = " + sumOfWeights);

        ArrayList<String> strings = Arrays.stream(array).collect(ArrayList::new, (c, e) -> c.add(e + ""), ArrayList::addAll);
        System.out.println(strings);

        List<String> weights = widgetList.stream().map(t -> t.getWeight() + "").collect(Collectors.toList());
        System.out.println(weights);

        OptionalInt min = Arrays.stream(array).min();
        OptionalInt max = Arrays.stream(array).max();
        long count = Arrays.stream(array).count();
        System.out.println("min = " + min + " max = " + max + " count = " + count);

        boolean anyMatch = Arrays.stream(array).anyMatch(t -> t > 5);
        boolean allMatch = Arrays.stream(array).allMatch(t -> t > 5);
        boolean noneMatch = Arrays.stream(array).noneMatch(t -> t > 5);
        System.out.println("anyMatch = " + anyMatch + " allMatch = " + allMatch + " noneMatch = " + noneMatch);

        OptionalInt findAny = Arrays.stream(array).parallel().findAny();
        OptionalInt findFirst = Arrays.stream(array).findFirst();
        System.out.println("findAny = " + findAny + " findFirst = " + findFirst);
    }

参考文献

Stream

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:36:57  更:2021-08-16 11:38:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 1:25:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码