探索 Java 8 中的 Stream 流:构建流的多种方式

在这里插入图片描述
人嘛,要懂得避嫌…

开篇引入

Java 8引入了Stream流作为一项新的特性,它是用来处理集合数据的一种函数式编程方式。Stream流提供了一种更简洁、高效和易于理解的方法来操作集合数据,同时也能够实现并行处理,以提高性能。

以下是Stream流的一些重要特征和用法:

  1. 流的创建:可以从集合、数组、I/O通道等多种数据源创建Stream流。例如,使用Collection.stream()方法可以将集合转换为流,使用Arrays.stream()可以将数组转换为流。

  2. 中间操作:Stream流支持各种中间操作,这些操作允许对流中的元素进行过滤、映射、排序等操作,而不会修改原始数据。一些常见的中间操作包括filter(过滤元素)、map(映射元素)、sorted(排序元素)等。

  3. 终端操作:终端操作是对流进行最终操作,它们触发实际的计算并生成结果。一些常见的终端操作包括forEach(遍历元素并执行操作)、collect(将流中的元素收集到一个集合中)、count(计算元素个数)等。

  4. 延迟执行:Stream操作是延迟执行的,这意味着中间操作可以在不实际计算的情况下链接在一起。只有在调用终端操作时,才会触发流的处理。

  5. 并行处理:Stream流支持并行处理,通过使用parallelStream()方法,可以轻松地将流的处理分布到多个处理器核心上,以提高性能。

  6. 函数式编程风格:Stream流鼓励使用函数式编程风格,其中操作是以lambda表达式的形式传递的,使代码更具表达力和简洁。

以下是一个示例,演示了如何使用Stream流来操作一个集合:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

int sum = numbers.stream()
                .filter(n -> n % 2 == 0) // 过滤偶数
                .map(n -> n * 2) // 将偶数翻倍
                .reduce(0, Integer::sum); // 求和

System.out.println("偶数的翻倍之和为: " + sum);

这只是Stream流的一个简单示例,它展示了Stream流的一些常见操作,如过滤、映射和汇总。通过Stream流,可以以更简洁和可读的方式处理集合数据,减少了样板代码,提高了代码质量和可维护性。下面我们将对构建流的多种方式多种方式展开做一个详细阐述。

1.从集合创建流

从集合创建Stream流非常简单,可以使用集合类的stream()方法来获取一个Stream对象。下面我将展示如何从集合创建Stream,并结合实际应用提供两个代码示例。

示例1:从List创建Stream

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamCreationExample {

    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        names.add("David");
        names.add("Eve");

        // 创建一个Stream流
        Stream<String> nameStream = names.stream();

        // 使用Stream流进行操作
        nameStream
            .filter(name -> name.startsWith("A"))
            .forEach(System.out::println);
    }
}

这个示例中,我们首先创建了一个包含一些姓名的List集合,然后使用names.stream()方法创建了一个Stream流。接着,我们使用filter中间操作筛选出以"A"开头的姓名,并使用forEach终端操作打印输出结果。

示例2:从Map创建Stream

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

public class StreamCreationFromMapExample {

    public static void main(String[] args) {
        Map<Integer, String> studentMap = new HashMap<>();
        studentMap.put(1, "Alice");
        studentMap.put(2, "Bob");
        studentMap.put(3, "Charlie");
        studentMap.put(4, "David");
        studentMap.put(5, "Eve");

        // 从Map的键集合创建Stream
        Stream<Integer> studentIdsStream = studentMap.keySet().stream();

        // 使用Stream流进行操作
        studentIdsStream
            .filter(id -> id % 2 == 0)
            .forEach(id -> System.out.println(id + ": " + studentMap.get(id)));
    }
}

这个示例中,我们创建了一个包含学生ID和姓名的Map,然后使用studentMap.keySet().stream()方法从Map的键集合创建了一个Stream流。接着,我们使用filter中间操作筛选出偶数的学生ID,并使用forEach终端操作打印出相应的学生信息。

2.从数组创建流

从数组创建Stream流也非常简单,Java 8 提供了Arrays.stream() 方法,它允许将一个数组转换为一个Stream流。下面我将详细介绍如何从数组创建Stream,并提供两个代码示例。

示例1:从整数数组创建Stream

import java.util.Arrays;
import java.util.stream.IntStream;

public class StreamCreationFromArrayExample {

    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        // 从整数数组创建IntStream
        IntStream numberStream = Arrays.stream(numbers);

        // 使用Stream流进行操作
        int sum = numberStream
            .filter(n -> n % 2 == 0)
            .map(n -> n * 2)
            .sum();

        System.out.println("偶数的翻倍之和为: " + sum);
    }
}

在这个示例中,我们首先创建了一个整数数组 numbers,然后使用 Arrays.stream(numbers) 方法将它转换为一个 IntStream 流。接着,我们使用该流进行一系列操作,包括筛选出偶数并将其翻倍,最后计算它们的总和。

示例2:从字符串数组创建Stream

import java.util.Arrays;
import java.util.stream.Stream;

public class StreamCreationFromArrayExample {

    public static void main(String[] args) {
        String[] words = {"apple", "banana", "cherry", "date", "elderberry"};

        // 从字符串数组创建Stream
        Stream<String> wordStream = Arrays.stream(words);

        // 使用Stream流进行操作
        wordStream
            .filter(word -> word.startsWith("b"))
            .map(String::toUpperCase)
            .forEach(System.out::println);
    }
}

在这个示例中,我们创建了一个字符串数组 words,然后使用 Arrays.stream(words) 方法将它转换为一个 Stream 流。接着,我们使用流进行操作,包括筛选出以字母 “b” 开头的单词,并将它们转换为大写形式后打印输出。

3.静态工厂方法

Java 8也引入了一些静态工厂方法来创建Stream流,这些方法使得创建Stream流变得更加简便和灵活。下面我将详细介绍这些静态工厂方法,并提供两个代码示例。

静态工厂方法创建Stream

  1. Stream.of(T... values):通过将一个可变参数的元素列表传递给Stream.of方法来创建一个包含这些元素的Stream流。这对于创建具有少量元素的流非常方便。

  2. Stream.empty():使用Stream.empty()方法创建一个空的Stream流。

  3. Stream.generate(Supplier<T> s):通过提供一个Supplier函数来创建一个无限大小的Stream流,该函数会生成元素。通常,需要使用limit操作限制生成的元素数量。

  4. Stream.iterate(T seed, UnaryOperator<T> f):通过提供初始值(seed)和一个一元操作函数(UnaryOperator)来创建一个包含无限序列的Stream流。例如,可以使用Stream.iterate(0, n -> n + 1)来创建一个自然数序列的Stream流。

示例1:使用Stream.of创建Stream

import java.util.stream.Stream;

public class StreamFactoryExample {

    public static void main(String[] args) {
        // 使用Stream.of创建Stream流
        Stream<String> stream = Stream.of("Apple", "Banana", "Cherry", "Date");

        // 打印Stream中的元素
        stream.forEach(System.out::println);
    }
}

这个示例使用Stream.of静态工厂方法创建了一个包含水果名称的Stream流,并使用forEach终端操作打印出每个水果的名称。

示例2:使用Stream.generate创建Stream

import java.util.Random;
import java.util.stream.Stream;

public class StreamGenerateExample {

    public static void main(String[] args) {
        // 使用Stream.generate创建随机整数流
        Stream<Integer> randomIntStream = Stream.generate(() -> new Random().nextInt(100));

        // 限制流的元素数量,然后打印
        randomIntStream
            .limit(10)
            .forEach(System.out::println);
    }
}

在这个示例中,我们使用Stream.generate静态工厂方法创建了一个包含随机整数的Stream流。然后,我们使用limit操作限制了流中元素的数量,最后打印出了生成的随机整数。

这些静态工厂方法为创建不同类型的Stream提供了便捷的途径,使流的创建更加灵活和便捷。

4.使用 Stream.Builder

Stream.Builder是Java 8引入的用于构建流的一种方式。它允许逐个添加元素到流中,并最终构建一个Stream对象。这对于在迭代或生成元素的过程中构建流非常有用。

下面是如何使用Stream.Builder创建流的详细介绍,并提供两个代码示例。

使用Stream.Builder创建流的步骤:

  1. 创建Stream.Builder对象:首先,需要创建一个Stream.Builder对象。

  2. 添加元素:然后,使用Stream.Builderadd方法逐个添加元素到流中。

  3. 构建流:一旦添加了所有元素,可以调用Stream.Builderbuild方法来构建Stream对象。

示例1:使用Stream.Builder创建流并过滤奇数

import java.util.stream.Stream;

public class StreamBuilderExample {

    public static void main(String[] args) {
        Stream.Builder<Integer> builder = Stream.builder();

        // 添加元素到Stream
        for (int i = 1; i <= 10; i++) {
            builder.accept(i);
        }

        // 构建Stream
        Stream<Integer> numberStream = builder.build();

        // 使用Stream操作
        numberStream
            .filter(n -> n % 2 == 0) // 过滤偶数
            .forEach(System.out::println);
    }
}

在这个示例中,我们首先创建了一个Stream.Builder对象,然后使用accept方法逐个添加1到10的整数到流中,最后使用filter中间操作筛选出偶数并使用forEach终端操作打印出结果。

示例2:使用Stream.Builder生成斐波那契数列

import java.util.stream.Stream;

public class FibonacciStreamExample {

    public static void main(String[] args) {
        Stream.Builder<Long> builder = Stream.builder();

        long a = 0, b = 1;
        int count = 10;

        for (int i = 0; i < count; i++) {
            builder.accept(a);
            long next = a + b;
            a = b;
            b = next;
        }

        Stream<Long> fibonacciStream = builder.build();

        fibonacciStream.forEach(System.out::println);
    }
}

在这个示例中,我们使用Stream.Builder生成斐波那契数列的前10个数字。我们首先创建一个Stream.Builder对象,然后使用循环逐个添加斐波那契数列的元素,最后使用forEach终端操作打印出结果。

Stream.Builder适用于需要逐个生成元素并构建流的情况,使代码更加清晰和灵活。

5. 从文件创建流

在Java中,可以从文件创建Stream流以便进行文件的读取和处理。通常,可以使用java.nio.file包中的类来实现这一目的。以下是如何从文件创建流的方法以及两个代码示例:

方法1:使用Files.lines方法创建文本文件的流

Files.lines方法允许创建一个包含文件内容的Stream<String>,适用于文本文件的逐行读取。该方法接受文件路径作为参数,并返回一个Stream对象。

下面是一个示例:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class FileToStreamExample {

    public static void main(String[] args) {
        String filePath = "sample.txt"; // 文件路径

        try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
            lines.forEach(System.out::println); // 逐行打印文件内容
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,我们使用Files.lines方法打开名为"sample.txt"的文本文件,并将其内容逐行打印到控制台。

方法2:使用Files.newInputStream方法创建二进制文件的流

如果要处理二进制文件,例如图像或音频文件,可以使用Files.newInputStream方法创建一个InputStream,然后将其转换为Stream。下面是一个示例:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class BinaryFileToStreamExample {

    public static void main(String[] args) {
        String filePath = "image.jpg"; // 二进制文件路径

        try {
            Path path = Paths.get(filePath);
            Stream<Byte> byteStream = Files.newInputStream(path)
                                          .map(b -> (byte) b);

            byteStream.forEach(System.out::println); // 逐字节打印二进制文件内容
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,我们使用Files.newInputStream方法创建一个输入流,然后将其映射为Stream<Byte>,并最终逐字节打印二进制文件的内容。

无论是文本文件还是二进制文件,从文件创建Stream流都是非常有用的,它使文件的读取和处理变得更加方便和灵活。在处理文件时,不要忘记适当地处理可能出现的IOException异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/114939.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uni-app 解决钉钉小程序日期组件uni-datetime-picker不兼容ios问题

最近在使用uni-app开发 钉钉小程序 &#xff0c;遇到一个ios的兼容性问题 uni-datetime-picker 组件在模拟器上可以使用&#xff0c;在真机上不生效问题 文章目录 1. 不兼容的写法&#xff0c;uni-datetime-picker 不兼容IOS2. 兼容的写法&#xff0c;使用 dd.datePicker 实现。…

windwos10搭建我的世界服务器,并通过内网穿透实现联机游戏Minecraft

文章目录 1. Java环境搭建2.安装我的世界Minecraft服务3. 启动我的世界服务4.局域网测试连接我的世界服务器5. 安装cpolar内网穿透6. 创建隧道映射内网端口7. 测试公网远程联机8. 配置固定TCP端口地址8.1 保留一个固定tcp地址8.2 配置固定tcp地址 9. 使用固定公网地址远程联机 …

系列四、全局配置文件mybatis-config.xml

一、全局配置文件中的属性 mybatis全局配置中的文件非常多&#xff0c;主要有如下几个&#xff1a; properties&#xff08;属性&#xff09;settings&#xff08;全局配置参数&#xff09;typeAliases&#xff08;类型别名&#xff09;typeHandlers&#xff08;类型处理器&am…

整理10个地推拉新app接单平台,免费一手推广渠道平台干货分享

1. 聚量推客&#xff1a; “聚量推客”汇聚了众多市场上有的和没有的地推网推拉新接单项目&#xff0c;目前比较火热&#xff0c;我们做地推和网推从业者如果长期在这行业去做推广可以使用这个平台&#xff0c;价格高数据也好&#xff0c;大部分拉新项目也都是官签一手资源 一…

自己动手实现一个深度学习算法——三、神经网络的学习

文章目录 1.从数据中学习1&#xff09;数据驱动2&#xff09;训练数据和测试数据 2.损失函数1)均方误差2)交叉熵误差3)mini-batch学习 3.数值微分1&#xff09;概念2&#xff09;数值微分实现 4.梯度1&#xff09;实现2&#xff09;梯度法3&#xff09;梯度法实现4&#xff09;…

建议收藏《2023华为海思实习笔试-数字芯片真题+解析》(附下载)

华为海思一直以来是从业者想要进入的热门公司。但是岗位就那么多&#xff0c;在面试的时候&#xff0c;很多同学因为准备不充分&#xff0c;与岗位失之交臂&#xff0c;无缘进入该公司。今天为大家带来《2023华为海思实习笔试-数字芯片真题解析》题目来源于众多网友对笔试的记录…

FBM232 P0926GW 一个基于PC的Studio应用程序

FBM232 P0926GW 一个基于PC的Studio应用程序 告别自定义编程&#xff0c;向S88 Builder问好。它可以帮助您轻松地将泵、混合器和阀门等单个批处理设备配置为特定的协调任务&#xff0c;如灌装、加热和混合。 S88 Builder是什么&#xff1f;它包括一个基于PC的Studio应用程序&…

ubuntu 分区 方案

ubuntu 分区 方案 自动分区啥样子的&#xff1f; 手动分区 需要怎么操作&#xff1f; 注意点是啥&#xff1f; swap分区 要和 内存大小 差不多 安装ubuntu系统时硬盘分区方案 硬盘分区概述 一块硬盘最多可以分4个主分区&#xff0c;主分区之外的成为扩展分区。硬盘可以没有…

javaEE -13(6000字CSS入门级教程 - 2)

一&#xff1a;Chrome 调试工具 – 查看 CSS 属性 首先打开浏览器&#xff0c;接着有两种方式可以打开 Chrome 调试工具 直接按 F12 键鼠标右键页面 > 检查元素 点开检查即可 标签页含义&#xff1a; elements 查看标签结构console 查看控制台source 查看源码断点调试ne…

开源的网站数据分析统计平台——Matomo

Matomo 文章目录 Matomo前言一、环境准备1. 整体安装流程2.安装PHP 7.3.303.nginx配置4.安装matomo4.1 访问安装页面 http://192.168.10.45:8088/index.php4.2 连接数据库4.3 设置管理员账号4.4 生成js跟踪代码4.5 安装完成4.6 警告修改4.7 刷新页面&#xff0c;就可以看到登陆…

AI智能分析网关高空抛物算法如何实时检测高楼外立面剥落?

高楼外立面剥落是一种十分危险的行为&#xff0c;会造成严重的人身伤害和财产损失。TSINGSEE青犀智能分析网关利用高楼外立面剥落的信息&#xff0c;结合高空抛物算法来进行处理就可很好解决此问题。 1. 数据收集 首先&#xff0c;需要收集关于高楼外立面剥落的数据。这可以通…

Android应用集成RabbitMQ消息处理指南

Android应用集成RabbitMQ消息处理指南 RabbitMQ1、前言2、RabbitMQ简介2.1、什么是RabbitMQ2.2、RabbitMQ的特点2.3、RabbitMQ的工作原理2.4、RabbitMQ中几个重要的概念 3、在Android Studio中集成RabbitMQ3.1、在Manifest中添加权限&#xff1a;3.2、在build.gradle(:app)下添…

数据中心如何散热?

数据中心的散热是一个非常重要的问题&#xff0c;因为数据中心内运行的服务器、存储设备以及网络设备等都会产生大量的热量&#xff0c;如果不能有效地进行散热&#xff0c;将会导致设备故障和性能下降。下面是一些常见的数据中心散热方法&#xff1a; 空调系统&#xff1a;数据…

Attention is all you need 论文阅读

论文链接 Attention is all you need 0. Abstract 主要序列转导模型基于复杂的循环或卷积神经网络&#xff0c;包括编码器和解码器。性能最好的模型还通过注意力机制连接编码器和解码器提出Transformer&#xff0c;它 完全基于注意力机制&#xff0c;完全不需要递归和卷积对两…

【机器学习】五、贝叶斯分类

我想说&#xff1a;“任何事件都是条件概率。”为什么呢&#xff1f;因为我认为&#xff0c;任何事件的发生都不是完全偶然的&#xff0c;它都会以其他事件的发生为基础。换句话说&#xff0c;条件概率就是在其他事件发生的基础上&#xff0c;某事件发生的概率。 条件概率是朴…

rabbitmq的confirm模式获取correlationData为null解决办法

回调函数confirm中的correlationDatanull // 实现confirm回调,发送到和没发送到exchange,都触发 Override public void confirm(CorrelationData correlationData, boolean ack, String cause) {// 参数说明:// correlationData: 相关数据,可以在发送消息时,进行设置该参数// …

我在Vscode学OpenCV 处理图像

既然我们是面向Python的OpenCV&#xff08;OpenCV for Python&#xff09;那我们就必须要熟悉Numpy这个库&#xff0c;尤其是其中的数组的库&#xff0c;Python是没有数组的&#xff0c;唯有借助他库才有所实现想要的目的。 # 老三样库--事先导入 import numpy as np import c…

Python操作CMD大揭秘!轻松玩转命令行控制

导语&#xff1a; 命令行界面&#xff08;Command Line Interface&#xff0c;简称CLI&#xff09;是计算机操作系统中一种基于文本的用户界面&#xff0c;通过输入命令来与计算机进行交互。Python作为一门强大的编程语言&#xff0c;提供了丰富的库和模块&#xff0c;可以方便…

Android系统Launcher启动流程学习(一)init启动部分

init进程学习&#xff1a; 文件路径system/core/init/init.cpp 解析init.rc配置文件&#xff0c;首先开启ServiceManager和MediaServer等关键进程init进程fork启动Zygote服务进程处理子进程的终止(signal方式)提供属性服务的功能 int main(int argc, char** argv) {//注释一…

机器学习快速入门教程 Scikit-Learn实现

机器学习是什么? 机器学习是一帮计算机科学家想让计算机像人一样思考所研发出来的计算机理论。他们曾经说过,人和计算机其实本没有差别,同样都是一大批互相连接的信息传递和存储元素所组成的系统。所以有了这样的想法,加上他们得天独厚的数学功底,机器学习的前身也就孕育而生…