流知识超详细总结!一文搞懂!

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,5000CU*H 3个月
简介: 流知识超详细总结!一文搞懂!


流思维导图image.png

方法

操作方法
list.stream().filter()

list.stream().filter() 是使用 Java 8 引入的 Stream API 对 List 进行过滤操作的语法。

list 是一个 List 对象,

.stream() 方法将其转换为一个流(Stream)(注意所有的集合都可以转化为一个流)

下面是一个简单的示例,展示了如何使用 .filter() 方法对 List 进行过滤操作:

list
                .stream()
                .filter(name->name.startsWith("h"))//.filter(name->name.length()==4)
                .forEach(e-> System.out.println(e));

filter()方法只会过滤出Predicate返回值为TRUE的值,通过predicate函数式接口,定义传入参数和判断逻辑,以用来判断过滤条件

stream().map( Function )

map方法通常用于将一个流中的元素映射为另一个流中的元素,即对流中的每个元素应用一个函数,将其转换为另一个元素。

List<String> words = Arrays.asList("Hello", "World");
List<String> uniqueLetters = words.stream()
        .flatMap(word -> Arrays.stream(word.split("")))
        .distinct()
        .collect(Collectors.toList());

System.out.println(uniqueLetters); // Output: [H, e, l, o, W, r, d]


//map()的两个作用
//转化数据类型
Stream<String> stringStream = Stream.of("1","2","3");
Stream<Integer> integerStream = stringStream.map(Integer::valueOf);

//数据过滤后的数据处理
//业务场景:过滤出整数流的偶数并且乘上2
Stream<Integer> newStream = Stream.of(1,2,3,4,5);
System.out.println(newStream.filter(m -> m % 2 == 0).map(n -> n * 2).collect(Collectors.toList()));
Sorted

使用sorted方法可以对流中的元素进行排序。它接受一个可选的Comparator比较器作为参数,用于指定元素的排序规则。

Distinct
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 3, 2, 1);
List<Integer> uniqueNumbers = numbers.stream()
        .distinct()
        .collect(Collectors.toList());

使用distinct方法可以去除流中的重复元素,只保留唯一的元素。

终端方法
stream().collect(Collectors.toList())

collect方法接受返回值(通常转化为列表)

异步处理方法
顺序流和平行流

顺序流(Sequential Stream)是默认的流类型,在顺序流中,操作是按照顺序(流的开始到结束)依次应用于每个元素的。顺序流适用于单线程环境,每个操作都在前一个操作完成后依次执行

平行流(Parallel Stream)是流的另一种类型,它可以将操作并行执行,将流中的元素划分为多个部分,并利用多个线程同时处理这些部分。平行流适用于多核处理器或需要处理大量数据的情况,可以显著提高处理速度。最后将多段数据进行合并(合并数据是很快的,但是顺序处理数据是很慢的。)

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

List<Integer> result = numbers.stream()
                              .map(n -> n * 2)
                              .filter(n -> n % 3 == 0)
                              .collect(Collectors.toList());

平行流的转化只需调用流中的parallel()方法

List<Integer> result = numbers.stream()
                              .parallel() // 将顺序流转换为平行流
                              .map(n -> n * 2)
                              .filter(n -> n % 3 == 0)
                              .collect(Collectors.toList());

流(统一处理各类型的数据流的输入输出操作的抽象的数据处理方法)

在Java中,流(Stream)是一种用于处理输入和输出操作抽象概念。它提供了一种统一的方式来处理各种类型的数据流,无论是从文件、网络连接还是其他数据源。流提供了丰富的方法和操作,使得数据的处理更加简洁、灵活和高效。

输入流用于从数据源读取数据,输出流用于将数据写入到目标位置。流的处理通常是按照顺序一次性处理数据的一部分,而不是一次性将整个数据加载到内存中。

流的特性
  1. 抽象和统一:流提供了一种抽象和统一的方式来处理输入和输出操作。不论数据来自于文件、网络还是其他数据源,都可以使用相同的方式进行处理。
  2. 高效和延迟处理:流的处理是按需进行的,只有在需要时才会读取或写入数据,这样可以节省内存资源并提高处理效率。流还支持延迟处理,可以将多个操作组合起来,一次性进行处理,减少中间过程的数据存储和交互。
  3. 方法丰富:Java流提供了丰富的方法和操作,如过滤、映射、排序、聚合等,可以灵活地对数据进行处理和转换。这些方法可以通过链式调用,使代码更加简洁和可读。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class StreamExample {
   
   
    public static void main(String[] args) {
   
   
        try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {
   
   
            // 从文件中读取数据并使用流进行处理
            reader.lines()
                    .filter(line -> line.contains("Java"))
                    .map(String::toUpperCase)
                    .forEach(System.out::println);
            //我们使用流的方法链来对数据进行处理:首先使用filter方法过滤出包含"Java"的行,然后使用map方法将行转换为大写,最后使用forEach方法打印处理后的行。
        } catch (IOException e) {
   
   
            e.printStackTrace();
        }
    }
}
流的定义

网络流:网络传输

文件流:读写文件

字节流:二进制数据

字符流:文本数据

不同数据类型的输入和输出流
  1. 字节流(Byte Streams):
    • InputStreamOutputStream是字节流的抽象基类。它们用于读取和写入字节数据。
    • FileInputStreamFileOutputStream用于读取和写入文件中的字节数据。
    • ByteArrayInputStreamByteArrayOutputStream用于读取和写入字节数组中的数据。
    • BufferedInputStreamBufferedOutputStream提供了缓冲功能,可以提高读写效率。
  2. 字符流(Character Streams):
    • ReaderWriter是字符流的抽象基类。它们用于读取和写入字符数据。
    • FileReaderFileWriter用于读取和写入文件中的字符数据。
    • BufferedReaderBufferedWriter提供了缓冲功能和更高效的字符处理。
  3. 基本数据类型流:
    • DataInputStreamDataOutputStream用于读取和写入基本数据类型(如int、double、boolean等)的数据。
    • ObjectInputStreamObjectOutputStream用于读取和写入Java对象。
  4. 字符串流:
    • StringReaderStringWriter用于读取和写入字符串数据。
  5. 压缩流:
    • ZipInputStreamZipOutputStream用于读取和写入压缩文件。
    • GZIPInputStreamGZIPOutputStream用于读取和写入GZIP格式的压缩文件。
  6. 网络流:
    • SocketServerSocket用于在网络上进行数据通信。
    • SocketInputStreamSocketOutputStream用于读取和写入网络流。
流的学习框架

序列化

涉及到接口java.io.Serializable(Serializable:可序列化的)。Serializable是一个标记接口,无需实现任何方法,只是标记了该类的对象可以被序列化。

定义

序列化是指将对象转换为字节流的过程,以便在网络上传输或持久化到磁盘中。反序列化则是将字节流转换回对象的过程。字符在网络中流动中是明文,很容易被解析,是不安全的,所以需要被序列化。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6PhyaCD-1686149133542)(./d9feafe3b388487c896126c4724a9c57.png)]

不安全传输的解决方法
  1. 使用加密传输:通过使用安全套接层(SSL)或传输层安全(TLS)等加密协议,对数据进行加密传输。这可以防止窃听者获取敏感数据。
  2. 数字签名和证书验证:使用数字签名和证书验证来确保通信的完整性和身份验证。发送方可以使用私钥对数据进行签名,接收方使用发送方的公钥来验证签名的有效性。证书验证可以确保通信双方的身份。
  3. 身份验证和授权:要求通信双方进行身份验证,确保只有授权的用户或设备可以进行通信。可以使用用户名和密码、令牌、双因素认证等方式进行身份验证,并基于角色或权限进行授权。
  4. 防止重放攻击:在传输过程中,防止恶意用户重复发送已经被捕获的通信数据,可以使用一次性令牌、时间戳或随机数等方式来防止重放攻击。
  5. 数据完整性校验:通过使用消息摘要算法(如SHA-256)对数据进行哈希计算,发送方将计算得到的摘要附加到数据中,接收方收到数据后重新计算摘要并与接收到的摘要进行比对,以确保数据的完整性。

随机读写流

定义:支持在文件的任意位置进行读写操作的流。可以利用随机读写流进行数据切割。

数据切割
 public static void splitFile(int chunkSize,String filePath) throws IOException{
   
   
        //读取文件
        FileReader fr = new FileReader(filePath);
        BufferedReader br = new BufferedReader(fr);
        //切割文件
        char[] buffer = new char[chunkSize];
        int count = 0;
        // br.read(buffer) 从输入流中读取一定字符数并且存储在buffer数组中,同时也会返回实际读取的字符数
        while(-1 != (count = br.read(buffer))){
   
   
            FileWriter fw = new FileWriter(filePath + "." + count);
            //通过字符串拼接构造一个包含文件路径和数据块大小的文件名,并将count大小的数据块存储到文件之中
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(buffer,0,count);
            bw.close();
        }
        fr.close();
        br.close();
    }

如何实现字节/字符流的数据切割?

  1. 先将数据块切分为长度为chunkSize的数据块(字符数组)

    chunkSize的大小要根据实际的业务进行确定。

  2. 读取输入流中的数据,存入数据块中,并且返回实际读取的数据大小。

    while(-1 != (count = br.read(buffer)))
    
  3. 根据获取的数据大小,将buffer中的数据写入输出流(自定义输出流的路径:文件路径 + 数据块大小)

数据切割的作用

  1. 提高传输效率
  2. 避免内存溢出
  3. 支持断点续传:对每个数据块都是单独进行传输的,如果出现网络中断的情况,出错时只需单独处理中断的数据块即可。
“读取是输入,写入是输出”

将数据的流动比作水流,从外部获取数据(例如文件、网络等)并将其引入到程序中时,我们将数据视为流入程序,因此称之为输入。相反,当程序将数据发送到外部(例如写入文件、发送网络请求等),我们将数据视为流出程序,因此称之为输出。

协议

等级 协议名称 协议特性
底层 IP(Internet Protocol)互联网协议 1.定义数据包的格式数据包像信一样都需要有固定的格式)(存放数据格式:从哪个字节到哪个字节存放的是数据的长度,数据的内容,双方的地址,端口号…),分割、标识数据包,确定传输路径2.所有网络传输都基于IP
底层 TCP协议/UDP协议(Transmission Control Protocol/User Datagram Protocol) 传输控制协议/用户包协议 1.TCP面向连接(常连接),UDP无连接(用户的两台电脑自成客户端)2.TCP可靠 UDP快速3.TCP用于文件传输,电子邮件;UDP用于实时视频,音频(用户之间
底层 HTTP协议(S)(Hypertext Transfer Protocol)超文本传输协议 1.对TTP协议的一种包装,面向web。2.无状态:基于单次请求给单次反馈,不需要常连接,反馈完连接就断开了。
底层 SMTP(Simple Mail Transfer Protocol)简单邮件传输协议 面向邮箱 上班用邮件
高级 FTP(File Transfer Protocol) 文件传输协议 文件传输 数据传到hadoop

以QQ为例

QQ中既有TCP/UDP,聊天是通过UDP协议,登陆状态的维持/文件的传输是通过TCP协议,实际上没有办法有那么强大的服务器能够支撑数十亿人口并发量,因此,实际上,在聊天的过程中将用户的两台电脑自己互相作为客户端即可,也就是说这方面并不需要我控制。有限的资源就投入到登录和文件传输上面,因为聊天丢几帧影响也不大。

TCP/UDP 与 IP

IP负责将数据包从源主机传递到目标主机,TCP/UDP负责将数据打包成数据包,并在不同主机之间建立连接与传输。

TCP/UDP打包好了货物,搭好了桥,IP是邮递员负责将打包好的货物记录好信息,处理好,进行派送。

流计算与分布式计算的区别

流计算:用本机cpu和本地的磁盘,将磁盘的文件调到内存中,并用cpu进行计算

分布式计算:将一个计算任务分成子任务,并交给多台计算机并行计算,每台计算机都有自己的计算资源和存储资源,最后合并计算结果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-muZv3LkW-1686149133543)(./分布式计算.png)]流在分布式计算中的应用:利用网络流、字节流和文件流,将数据拷贝到远程的集群中。

网络流,字节流,文件流将任何一台机器的数据传输到网络能够到达的机器上去。

字节流主要面向文件拷贝,文件拷贝可以是群拷贝也可以是单独拷贝。

流操作的命名

字符输入节点流(不同类型主体(网络流/字符流/字节流/文件流)+输入/输出流+是否直接面向数据源(节点流/处理流))

目录
相关文章
|
存储 C语言 C++
66 C++ - 流的概念和流类库的结构
66 C++ - 流的概念和流类库的结构
81 0
|
7月前
|
JavaScript 前端开发 Java
流的概念,怎么处理
流的概念,怎么处理
|
Linux
44 # 流的原理
44 # 流的原理
64 0
|
存储 缓存 Java
1.10 I/O流 最全 最全 最全整理
1.10 I/O流 最全 最全 最全整理
88 1
Stream流操作-结果收集终止方法-第一篇
Stream流操作-结果收集终止方法-第一篇
86 3
|
前端开发
前端学习笔记202305学习笔记第二十五天-创建读取流2
前端学习笔记202305学习笔记第二十五天-创建读取流2
65 0
前端学习笔记202305学习笔记第二十五天-创建读取流2
|
前端开发
前端学习笔记202305学习笔记第二十五天-读写流组合使用
前端学习笔记202305学习笔记第二十五天-读写流组合使用
38 0
|
前端开发
前端学习笔记202305学习笔记第二十五天-创建读取流3
前端学习笔记202305学习笔记第二十五天-创建读取流3
41 0
|
自然语言处理 Java API
都2023年了,如果不会Stream流、函数式编程?你确定能看懂公司代码?
都2023年了,如果你不会Stream流、函数式编程?你确定能看懂同事写的代码? 那么建议来了解一下Stream流, 因为它使用简单,易操作,易上手而代码简洁,开发快速,一看就令人很爽😎😎😎 . 其实Stream流式编程表达式接近自然语言,易于理解 , 集万千优点与一身, 语法优美👉👉👉.下面来简单认识一下今天的主角Stream流吧
118 0
|
存储 算法 Java
JUC并发编程学习(十三)-学习Stream流的使用
JUC并发编程学习(十三)-学习Stream流的使用
JUC并发编程学习(十三)-学习Stream流的使用