编程学习
🗒️2019黑马java笔记⑤
00 分钟
2024-2-26
2024-3-2
type
status
date
slug
summary
tags
category
icon
password

3.IO流

3.1 IO流概述和分类【理解】

  • IO流介绍
    • IO:输入/输出(Input/Output)
    • 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
    • IO流就是用来处理设备间数据传输问题的。常见的应用:文件复制;文件上传;文件下载
  • IO流的分类
    • 按照数据的流向
      • 输入流:读数据
      • 输出流:写数据
    • 按照数据类型来分
      • 字节流
        • 字节输入流
        • 字节输出流
      • 字符流
        • 字符输入流
        • 字符输出流
  • IO流的使用场景
    • 如果操作的是纯文本文件,优先使用字符流
    • 如果操作的是图片、视频、音频等二进制文件。优先使用字节流
    • 如果不确定文件类型,优先使用字节流。字节流是万能的流

3.2字节流写数据【应用】

  • 字节流抽象基类
    • InputStream:这个抽象类是表示字节输入流的所有类的超类
    • OutputStream:这个抽象类是表示字节输出流的所有类的超类
    • 子类名特点:子类名称都是以其父类名作为子类名的后缀
  • 字节输出流
    • FileOutputStream(String name):创建文件输出流以指定的名称写入文件
  • 使用字节输出流写数据的步骤
    • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
    • 调用字节输出流对象的写数据方法
    • 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
  • 示例代码

    3.3字节流写数据的三种方式【应用】

    • 写数据的方法分类
      • 方法名
        说明
        void write(int b)
        将指定的字节写入此文件输出流 一次写一个字节数据
        void write(byte[] b)
        将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据
        void write(byte[] b, int off, int len)
        将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据
    • 示例代码

      3.4字节流写数据的两个小问题【应用】

      • 字节流写数据如何实现换行
        • windows:\r\n
        • linux:\n
        • mac:\r
      • 字节流写数据如何实现追加写入
        • public FileOutputStream(String name,boolean append)
        • 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
      • 示例代码

        3.5字节流写数据加异常处理【应用】

        • 异常处理格式
          • try-catch-finally
            • finally特点
              • 被finally控制的语句一定会执行,除非JVM退出
          • 示例代码

            3.6字节流读数据(一次读一个字节数据)【应用】

            • 字节输入流
              • FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream ,该文件由文件系统中的路径名name命名
            • 字节输入流读取数据的步骤
              • 创建字节输入流对象
              • 调用字节输入流对象的读数据方法
              • 释放资源
            • 示例代码

              3.7字节流复制文本文件【应用】

              • 案例需求
                • 把“E:\itcast\窗里窗外.txt”复制到模块目录下的“窗里窗外.txt”
              • 实现步骤
                • 复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
                • 数据源:
                  • E:\itcast\窗里窗外.txt --- 读数据 --- InputStream --- FileInputStream
                • 目的地:
                  • myByteStream\窗里窗外.txt --- 写数据 --- OutputStream --- FileOutputStream
              • 代码实现

                3.8字节流读数据(一次读一个字节数组数据)【应用】

                • 一次读一个字节数组的方法
                  • public int read(byte[] b):从输入流读取最多b.length个字节的数据
                  • 返回的是读入缓冲区的总字节数,也就是实际的读取字节个数
                • 示例代码

                  3.9字节流复制图片【应用】

                  • 案例需求
                    • 把“E:\itcast\mn.jpg”复制到模块目录下的“mn.jpg”
                  • 实现步骤
                    • 根据数据源创建字节输入流对象
                    • 根据目的地创建字节输出流对象
                    • 读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
                    • 释放资源
                  • 代码实现

                    1.字节缓冲流

                    1.1字节缓冲流构造方法【应用】

                    • 字节缓冲流介绍
                      • lBufferOutputStream:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
                      • lBufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
                    • 构造方法:
                      • 方法名
                        说明
                        BufferedOutputStream(OutputStream out)
                        创建字节缓冲输出流对象
                        BufferedInputStream(InputStream in)
                        创建字节缓冲输入流对象
                    • 示例代码

                      1.2字节流复制视频【应用】

                      • 案例需求
                        • 把“E:\itcast\字节流复制图片.avi”复制到模块目录下的“字节流复制图片.avi”
                      • 实现步骤
                        • 根据数据源创建字节输入流对象
                        • 根据目的地创建字节输出流对象
                        • 读写数据,复制视频
                        • 释放资源
                      • 代码实现

                        2.字符流

                        2.1为什么会出现字符流【理解】

                        • 字符流的介绍
                          • 由于字节流操作中文不是特别的方便,所以Java就提供字符流
                            字符流 = 字节流 + 编码表
                        • 中文的字节存储方式
                          • 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
                            汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数

                        2.2编码表【理解】

                        • 什么是字符集
                          • 是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
                            l计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
                        • 常见的字符集
                          • ASCII字符集:
                            • lASCII:是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
                              基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
                          • GBXXX字符集:
                            • GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等
                          • Unicode字符集:
                            • UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用 中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码
                              编码规则:
                              128个US-ASCII字符,只需一个字节编码
                              拉丁文等字符,需要二个字节编码
                              大部分常用字(含中文),使用三个字节编码
                              其他极少使用的Unicode辅助字符,使用四字节编码

                        2.3字符串中的编码解码问题【应用】

                        • 相关方法
                          • 方法名
                            说明
                            byte[] getBytes()
                            使用平台的默认字符集将该 String编码为一系列字节
                            byte[] getBytes(String charsetName)
                            使用指定的字符集将该 String编码为一系列字节
                            String(byte[] bytes)
                            使用平台的默认字符集解码指定的字节数组来创建字符串
                            String(byte[] bytes, String charsetName)
                            通过指定的字符集解码指定的字节数组来创建字符串
                        • 代码演示

                          2.4字符流中的编码解码问题【应用】

                          • 字符流中和编码解码问题相关的两个类
                            • InputStreamReader:是从字节流到字符流的桥梁
                              • 它读取字节,并使用指定的编码将其解码为字符
                                它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
                            • OutputStreamWriter:是从字符流到字节流的桥梁
                              • 是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
                                它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
                          • 构造方法
                            • 方法名
                              说明
                              InputStreamReader(InputStream in)
                              使用默认字符编码创建InputStreamReader对象
                              InputStreamReader(InputStream in,String chatset)
                              使用指定的字符编码创建InputStreamReader对象
                              OutputStreamWriter(OutputStream out)
                              使用默认字符编码创建OutputStreamWriter对象
                              OutputStreamWriter(OutputStream out,String charset)
                              使用指定的字符编码创建OutputStreamWriter对象
                          • 代码演示

                            2.5字符流写数据的5种方式【应用】

                            • 方法介绍
                              • 方法名
                                说明
                                void write(int c)
                                写一个字符
                                void write(char[] cbuf)
                                写入一个字符数组
                                void write(char[] cbuf, int off, int len)
                                写入字符数组的一部分
                                void write(String str)
                                写一个字符串
                                void write(String str, int off, int len)
                                写一个字符串的一部分
                            • 刷新和关闭的方法
                              • 方法名
                                说明
                                flush()
                                刷新流,之后还可以继续写数据
                                close()
                                关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据
                            • 代码演示

                              2.6字符流读数据的2种方式【应用】

                              • 方法介绍
                                • 方法名
                                  说明
                                  int read()
                                  一次读一个字符数据
                                  int read(char[] cbuf)
                                  一次读一个字符数组数据
                              • 代码演示

                                2.7字符流复制Java文件【应用】

                                • 案例需求
                                  • 把模块目录下的“ConversionStreamDemo.java” 复制到模块目录下的“Copy.java”
                                • 实现步骤
                                  • 根据数据源创建字符输入流对象
                                  • 根据目的地创建字符输出流对象
                                  • 读写数据,复制文件
                                  • 释放资源
                                • 代码实现

                                  2.8字符流复制Java文件改进版【应用】

                                  • 案例需求
                                    • 使用便捷流对象,把模块目录下的“ConversionStreamDemo.java” 复制到模块目录下的“Copy.java”
                                  • 实现步骤
                                    • 根据数据源创建字符输入流对象
                                    • 根据目的地创建字符输出流对象
                                    • 读写数据,复制文件
                                    • 释放资源
                                  • 代码实现

                                    2.9字符缓冲流【应用】

                                    • 字符缓冲流介绍
                                      • BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
                                      • BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
                                    • 构造方法
                                      • 方法名
                                        说明
                                        BufferedWriter(Writer out)
                                        创建字符缓冲输出流对象
                                        BufferedReader(Reader in)
                                        创建字符缓冲输入流对象
                                    • 代码演示

                                      2.10字符缓冲流复制Java文件【应用】

                                      • 案例需求
                                        • 把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java
                                      • 实现步骤
                                        • 根据数据源创建字符缓冲输入流对象
                                        • 根据目的地创建字符缓冲输出流对象
                                        • 读写数据,复制文件,使用字符缓冲流特有功能实现
                                        • 释放资源
                                      • 代码实现

                                        2.11字符缓冲流特有功能【应用】

                                        • 方法介绍
                                          • BufferedWriter:
                                            方法名
                                            说明
                                            void newLine()
                                            写一行行分隔符,行分隔符字符串由系统属性定义
                                            BufferedReader:
                                            方法名
                                            说明
                                            String readLine()
                                            读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null
                                        • 代码演示

                                          2.12字符缓冲流特有功能复制Java文件【应用】

                                          • 案例需求
                                            • 使用特有功能把模块目录下的ConversionStreamDemo.java 复制到模块目录下的 Copy.java
                                          • 实现步骤
                                            • 根据数据源创建字符缓冲输入流对象
                                            • 根据目的地创建字符缓冲输出流对象
                                            • 读写数据,复制文件,使用字符缓冲流特有功能实现
                                            • 释放资源
                                          • 代码实现

                                            2.13IO流小结【理解】

                                            • 字节流
                                              • notion image
                                            • 字符流
                                              • notion image

                                            3练习案例

                                            3.1集合到文件【应用】

                                            • 案例需求
                                              • 把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个集合元素
                                            • 实现步骤
                                              • 创建字符缓冲输入流对象
                                              • 创建ArrayList集合对象
                                              • 调用字符缓冲输入流对象的方法读数据
                                              • 把读取到的字符串数据存储到集合中
                                              • 释放资源
                                              • 遍历集合
                                            • 代码实现

                                              3.2文件到集合【应用】

                                              • 案例需求
                                                • 把ArrayList集合中的字符串数据写入到文本文件。要求:每一个字符串元素作为文件中的一行数据
                                              • 实现步骤
                                                • 创建ArrayList集合
                                                • 往集合中存储字符串元素
                                                • 创建字符缓冲输出流对象
                                                • 遍历集合,得到每一个字符串数据
                                                • 调用字符缓冲输出流对象的方法写数据
                                                • 释放资源
                                              • 代码实现

                                                3.3点名器【应用】

                                                • 案例需求
                                                  • 我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随点名器
                                                • 实现步骤
                                                  • 创建字符缓冲输入流对象
                                                  • 创建ArrayList集合对象
                                                  • 调用字符缓冲输入流对象的方法读数据
                                                  • 把读取到的字符串数据存储到集合中
                                                  • 释放资源
                                                  • 使用Random产生一个随机数,随机数的范围在:[0,集合的长度)
                                                  • 把第6步产生的随机数作为索引到ArrayList集合中获取值
                                                  • 把第7步得到的数据输出在控制台
                                                • 代码实现

                                                  3.4集合到文件改进版【应用】

                                                  • 案例需求
                                                    • 把ArrayList集合中的学生数据写入到文本文件。要求:每一个学生对象的数据作为文件中的一行数据 格式:学号,姓名,年龄,居住地 举例:itheima001,林青霞,30,西安
                                                  • 实现步骤
                                                    • 定义学生类
                                                    • 创建ArrayList集合
                                                    • 创建学生对象
                                                    • 把学生对象添加到集合中
                                                    • 创建字符缓冲输出流对象
                                                    • 遍历集合,得到每一个学生对象
                                                    • 把学生对象的数据拼接成指定格式的字符串
                                                    • 调用字符缓冲输出流对象的方法写数据
                                                    • 释放资源
                                                  • 代码实现
                                                    • 学生类
                                                      • 测试类

                                                      3.5文件到集合改进版【应用】

                                                      • 案例需求
                                                        • 把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个学生对象的成员变量值 举例:itheima001,林青霞,30,西安
                                                      • 实现步骤
                                                        • 定义学生类
                                                        • 创建字符缓冲输入流对象
                                                        • 创建ArrayList集合对象
                                                        • 调用字符缓冲输入流对象的方法读数据
                                                        • 把读取到的字符串数据用split()进行分割,得到一个字符串数组
                                                        • 创建学生对象
                                                        • 把字符串数组中的每一个元素取出来对应的赋值给学生对象的成员变量值
                                                        • 把学生对象添加到集合
                                                        • 释放资源
                                                        • 遍历集合
                                                      • 代码实现
                                                        • 学生类
                                                          • 同上
                                                        • 测试类

                                                        1.IO流案例

                                                        1.1集合到文件数据排序改进版【应用】

                                                        1.1.1案例需求

                                                        • 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)。要求按照成绩总分从高到低写入文本文件
                                                        • 格式:姓名,语文成绩,数学成绩,英语成绩 举例:林青霞,98,99,100

                                                        1.1.2分析步骤

                                                        1. 定义学生类
                                                        1. 创建TreeSet集合,通过比较器排序进行排序
                                                        1. 键盘录入学生数据
                                                        1. 创建学生对象,把键盘录入的数据对应赋值给学生对象的成员变量
                                                        1. 把学生对象添加到TreeSet集合
                                                        1. 创建字符缓冲输出流对象
                                                        1. 遍历集合,得到每一个学生对象
                                                        1. 把学生对象的数据拼接成指定格式的字符串
                                                        1. 调用字符缓冲输出流对象的方法写数据
                                                        1. 释放资源

                                                        1.1.3代码实现

                                                        • 学生类
                                                          • 测试类

                                                            1.2复制单级文件夹【应用】

                                                            1.2.1案例需求

                                                            • 把“E:\itcast”这个文件夹复制到模块目录下

                                                            1.2.2分析步骤

                                                            1. 创建数据源目录File对象,路径是E:\itcast
                                                            1. 获取数据源目录File对象的名称
                                                            1. 创建目的地目录File对象,路径由(模块名+第2步获取的名称)组成
                                                            1. 判断第3步创建的File是否存在,如果不存在,就创建
                                                            1. 获取数据源目录下所有文件的File数组
                                                            1. 遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
                                                            1. 获取数据源文件File对象的名称
                                                            1. 创建目的地文件File对象,路径由(目的地目录+第7步获取的名称)组成
                                                            1. 复制文件
                                                              1. 由于不清楚数据源目录下的文件都是什么类型的,所以采用字节流复制文件
                                                                采用参数为File的构造方法

                                                            1.2.3代码实现

                                                            1.3复制多级文件夹【应用】

                                                            1.3.1案例需求

                                                            • 把“E:\itcast”这个文件夹复制到 F盘目录下

                                                            1.3.2分析步骤

                                                            1. 创建数据源File对象,路径是E:\itcast
                                                            1. 创建目的地File对象,路径是F:\
                                                            1. 写方法实现文件夹的复制,参数为数据源File对象和目的地File对象
                                                            1. 判断数据源File是否是文件
                                                              1. 是文件:直接复制,用字节流
                                                                不是文件:

                                                            1.3.3代码实现

                                                            1.4复制文件的异常处理【应用】

                                                            1.4.1基本做法

                                                            1.4.2JDK7版本改进

                                                            1.4.3JDK9版本改进

                                                            2.IO特殊操作流

                                                            2.1标准输入流【应用】

                                                            • System类中有两个静态的成员变量
                                                              • public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
                                                              • public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
                                                            • 自己实现键盘录入数据

                                                              2.2标准输出流【应用】

                                                              • System类中有两个静态的成员变量
                                                                • public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
                                                                • public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
                                                              • 输出语句的本质:是一个标准的输出流
                                                                • PrintStream ps = System.out;
                                                                • PrintStream类有的方法,System.out都可以使用
                                                              • 示例代码

                                                                2.3字节打印流【应用】

                                                                • 打印流分类
                                                                  • 字节打印流:PrintStream
                                                                  • 字符打印流:PrintWriter
                                                                • 打印流的特点
                                                                  • 只负责输出数据,不负责读取数据
                                                                  • 永远不会抛出IOException
                                                                  • 有自己的特有方法
                                                                • 字节打印流
                                                                  • PrintStream(String fileName):使用指定的文件名创建新的打印流
                                                                  • 使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
                                                                  • 可以改变输出语句的目的地
                                                                    • public static void setOut(PrintStream out):重新分配“标准”输出流
                                                                • 示例代码

                                                                  2.4字符打印流【应用】

                                                                  • 字符打印流构造房方法
                                                                    • 方法名
                                                                      说明
                                                                      PrintWriter(String fileName)
                                                                      使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新
                                                                      PrintWriter(Writer out, boolean autoFlush)
                                                                      创建一个新的PrintWriter out:字符输出流 autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区
                                                                  • 示例代码

                                                                    2.5复制Java文件打印流改进版【应用】

                                                                    • 案例需求
                                                                      • 把模块目录下的PrintStreamDemo.java 复制到模块目录下的 Copy.java
                                                                    • 分析步骤
                                                                      • 根据数据源创建字符输入流对象
                                                                      • 根据目的地创建字符输出流对象
                                                                      • 读写数据,复制文件
                                                                      • 释放资源
                                                                    • 代码实现

                                                                      2.6对象序列化流【应用】

                                                                      • 对象序列化介绍
                                                                        • 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
                                                                        • 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
                                                                        • 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
                                                                        • 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
                                                                      • 对象序列化流: ObjectOutputStream
                                                                        • 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
                                                                      • 构造方法
                                                                        • 方法名
                                                                          说明
                                                                          ObjectOutputStream(OutputStream out)
                                                                          创建一个写入指定的OutputStream的ObjectOutputStream
                                                                      • 序列化对象的方法
                                                                        • 方法名
                                                                          说明
                                                                          void writeObject(Object obj)
                                                                          将指定的对象写入ObjectOutputStream
                                                                      • 示例代码
                                                                        • 学生类
                                                                          • 测试类
                                                                          • 注意事项
                                                                            • 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
                                                                            • Serializable是一个标记接口,实现该接口,不需要重写任何方法

                                                                          2.7对象反序列化流【应用】

                                                                          • 对象反序列化流: ObjectInputStream
                                                                            • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
                                                                          • 构造方法
                                                                            • 方法名
                                                                              说明
                                                                              ObjectInputStream(InputStream in)
                                                                              创建从指定的InputStream读取的ObjectInputStream
                                                                          • 反序列化对象的方法
                                                                            • 方法名
                                                                              说明
                                                                              Object readObject()
                                                                              从ObjectInputStream读取一个对象
                                                                          • 示例代码

                                                                            2.8serialVersionUID&transient【应用】

                                                                            • serialVersionUID
                                                                              • 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
                                                                                • 会出问题,会抛出InvalidClassException异常
                                                                              • 如果出问题了,如何解决呢?
                                                                                • 重新序列化
                                                                                • 给对象所属的类加一个serialVersionUID
                                                                                  • private static final long serialVersionUID = 42L;
                                                                            • transient
                                                                              • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
                                                                                • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
                                                                            • 示例代码
                                                                              • 学生类
                                                                                • 测试类

                                                                                3.Properties集合

                                                                                3.1Properties作为Map集合的使用【应用】

                                                                                • Properties介绍
                                                                                  • 是一个Map体系的集合类
                                                                                  • Properties可以保存到流中或从流中加载
                                                                                  • 属性列表中的每个键及其对应的值都是一个字符串
                                                                                • Properties基本使用

                                                                                  3.2Properties作为Map集合的特有方法【应用】

                                                                                  • 特有方法
                                                                                    • 方法名
                                                                                      说明
                                                                                      Object setProperty(String key, String value)
                                                                                      设置集合的键和值,都是String类型,底层调用 Hashtable方法 put
                                                                                      String getProperty(String key)
                                                                                      使用此属性列表中指定的键搜索属性
                                                                                      Set<String> stringPropertyNames()
                                                                                      从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
                                                                                  • 示例代码

                                                                                    3.3Properties和IO流相结合的方法【应用】

                                                                                    • 和IO流结合的方法
                                                                                      • 方法名
                                                                                        说明
                                                                                        void load(InputStream inStream)
                                                                                        从输入字节流读取属性列表(键和元素对)
                                                                                        void load(Reader reader)
                                                                                        从输入字符流读取属性列表(键和元素对)
                                                                                        void store(OutputStream out, String comments)
                                                                                        将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流
                                                                                        void store(Writer writer, String comments)
                                                                                        将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流
                                                                                    • 示例代码

                                                                                      3.4游戏次数案例【应用】

                                                                                      • 案例需求
                                                                                        • 实现猜数字小游戏只能试玩3次,如果还想玩,提示:游戏试玩已结束,想玩请充值(www.itcast.cn)
                                                                                      • 分析步骤
                                                                                          1. 写一个游戏类,里面有一个猜数字的小游戏
                                                                                          1. 写一个测试类,测试类中有main()方法,main()方法中写如下代码:
                                                                                            1. 从文件中读取数据到Properties集合,用load()方法实现
                                                                                              通过Properties集合获取到玩游戏的次数
                                                                                              判断次数是否到到3次了
                                                                                      • 代码实现

                                                                                        1.实现多线程

                                                                                        1.1进程和线程【理解】

                                                                                        • 进程:是正在运行的程序
                                                                                          • 是系统进行资源分配和调用的独立单位
                                                                                            每一个进程都有它自己的内存空间和系统资源
                                                                                        • 线程:是进程中的单个顺序控制流,是一条执行路径
                                                                                          • 单线程:一个进程如果只有一条执行路径,则称为单线程程序
                                                                                            多线程:一个进程如果有多条执行路径,则称为多线程程序

                                                                                        1.2实现多线程方式一:继承Thread类【应用】

                                                                                        • 方法介绍
                                                                                          • 方法名
                                                                                            说明
                                                                                            void run()
                                                                                            在线程开启后,此方法将被调用执行
                                                                                            void start()
                                                                                            使此线程开始执行,Java虚拟机会调用run方法()
                                                                                        • 实现步骤
                                                                                          • 定义一个类MyThread继承Thread类
                                                                                          • 在MyThread类中重写run()方法
                                                                                          • 创建MyThread类的对象
                                                                                          • 启动线程
                                                                                        • 代码演示
                                                                                          • 两个小问题
                                                                                            • 为什么要重写run()方法?
                                                                                              • 因为run()是用来封装被线程执行的代码
                                                                                            • run()方法和start()方法的区别?
                                                                                              • run():封装线程执行的代码,直接调用,相当于普通方法的调用
                                                                                                start():启动线程;然后由JVM调用此线程的run()方法

                                                                                          1.3设置和获取线程名称【应用】

                                                                                          • 方法介绍
                                                                                            • 方法名
                                                                                              说明
                                                                                              void setName(String name)
                                                                                              将此线程的名称更改为等于参数name
                                                                                              String getName()
                                                                                              返回此线程的名称
                                                                                              Thread currentThread()
                                                                                              返回对当前正在执行的线程对象的引用
                                                                                          • 代码演示

                                                                                            1.4线程优先级【应用】

                                                                                            • 线程调度
                                                                                              • 两种调度方式
                                                                                                • 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
                                                                                                • 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些
                                                                                              • Java使用的是抢占式调度模型
                                                                                              • 随机性
                                                                                                • 假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的
                                                                                            • 优先级相关方法
                                                                                              • 方法名
                                                                                                说明
                                                                                                final int getPriority()
                                                                                                返回此线程的优先级
                                                                                                final void setPriority(int newPriority)
                                                                                                更改此线程的优先级 线程默认优先级是5;线程优先级的范围是:1-10
                                                                                            • 代码演示

                                                                                              1.5线程控制【应用】

                                                                                              • 相关方法
                                                                                                • 方法名
                                                                                                  说明
                                                                                                  static void sleep(long millis)
                                                                                                  使当前正在执行的线程停留(暂停执行)指定的毫秒数
                                                                                                  void join()
                                                                                                  等待这个线程死亡
                                                                                                  void setDaemon(boolean on)
                                                                                                  将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出
                                                                                              • 代码演示

                                                                                                1.6线程的生命周期【理解】

                                                                                                线程一共有五种状态,线程在各种状态之间转换。
                                                                                                notion image

                                                                                                1.7实现多线程方式二:实现Runnable接口【应用】

                                                                                                • Thread构造方法
                                                                                                  • 方法名
                                                                                                    说明
                                                                                                    Thread(Runnable target)
                                                                                                    分配一个新的Thread对象
                                                                                                    Thread(Runnable target, String name)
                                                                                                    分配一个新的Thread对象
                                                                                                • 实现步骤
                                                                                                  • 定义一个类MyRunnable实现Runnable接口
                                                                                                  • 在MyRunnable类中重写run()方法
                                                                                                  • 创建MyRunnable类的对象
                                                                                                  • 创建Thread类的对象,把MyRunnable对象作为构造方法的参数
                                                                                                  • 启动线程
                                                                                                • 代码演示
                                                                                                  • 多线程的实现方案有两种
                                                                                                    • 继承Thread类
                                                                                                    • 实现Runnable接口
                                                                                                  • 相比继承Thread类,实现Runnable接口的好处
                                                                                                    • 避免了Java单继承的局限性
                                                                                                    • 适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想

                                                                                                  2.线程同步

                                                                                                  2.1卖票【应用】

                                                                                                  • 案例需求
                                                                                                    • 某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票
                                                                                                  • 实现步骤
                                                                                                    • 定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private int tickets = 100;
                                                                                                    • 在SellTicket类中重写run()方法实现卖票,代码步骤如下
                                                                                                    • 判断票数大于0,就卖票,并告知是哪个窗口卖的
                                                                                                    • 卖了票之后,总票数要减1
                                                                                                    • 票没有了,也可能有人来问,所以这里用死循环让卖票的动作一直执行
                                                                                                    • 定义一个测试类SellTicketDemo,里面有main方法,代码步骤如下
                                                                                                    • 创建SellTicket类的对象
                                                                                                    • 创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称
                                                                                                    • 启动线程
                                                                                                  • 代码实现
                                                                                                    • 执行结果
                                                                                                      • notion image

                                                                                                    2.2卖票案例的问题【理解】

                                                                                                    • 卖票出现了问题
                                                                                                      • 相同的票出现了多次
                                                                                                      • 出现了负数的票
                                                                                                    • 问题产生原因
                                                                                                      • 线程执行的随机性导致的

                                                                                                    2.3同步代码块解决数据安全问题【应用】

                                                                                                    • 安全问题出现的条件
                                                                                                      • 是多线程环境
                                                                                                      • 有共享数据
                                                                                                      • 有多条语句操作共享数据
                                                                                                    • 如何解决多线程安全问题呢?
                                                                                                      • 基本思想:让程序没有安全问题的环境
                                                                                                    • 怎么实现呢?
                                                                                                      • 把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可
                                                                                                      • Java提供了同步代码块的方式来解决
                                                                                                    • 同步代码块格式:
                                                                                                      • synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁
                                                                                                    • 同步的好处和弊端
                                                                                                      • 好处:解决了多线程的数据安全问题
                                                                                                      • 弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率
                                                                                                    • 代码演示

                                                                                                      2.4同步方法解决数据安全问题【应用】

                                                                                                      • 同步方法的格式
                                                                                                        • 同步方法:就是把synchronized关键字加到方法上
                                                                                                          同步方法的锁对象是什么呢?
                                                                                                          this
                                                                                                      • 静态同步方法
                                                                                                        • 同步静态方法:就是把synchronized关键字加到静态方法上
                                                                                                          同步静态方法的锁对象是什么呢?
                                                                                                          类名.class
                                                                                                      • 代码演示

                                                                                                        2.5线程安全的类【理解】

                                                                                                        • StringBuffer
                                                                                                          • 线程安全,可变的字符序列
                                                                                                          • 从版本JDK 5开始,被StringBuilder 替代。 通常应该使用StringBuilder类,因为它支持所有相同的操作,但它更快,因为它不执行同步
                                                                                                        • Vector
                                                                                                          • 从Java 2平台v1.2开始,该类改进了List接口,使其成为Java Collections Framework的成员。 与新的集合实现不同, Vector被同步。 如果不需要线程安全的实现,建议使用ArrayList代替Vector
                                                                                                        • Hashtable
                                                                                                          • 该类实现了一个哈希表,它将键映射到值。 任何非null对象都可以用作键或者值
                                                                                                          • 从Java 2平台v1.2开始,该类进行了改进,实现了Map接口,使其成为Java Collections Framework的成员。 与新的集合实现不同, Hashtable被同步。 如果不需要线程安全的实现,建议使用HashMap代替Hashtable

                                                                                                        2.6Lock锁【应用】

                                                                                                        虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock
                                                                                                        Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化
                                                                                                        • ReentrantLock构造方法
                                                                                                          • 方法名
                                                                                                            说明
                                                                                                            ReentrantLock()
                                                                                                            创建一个ReentrantLock的实例
                                                                                                        • 加锁解锁方法
                                                                                                          • 方法名
                                                                                                            说明
                                                                                                            void lock()
                                                                                                            获得锁
                                                                                                            void unlock()
                                                                                                            释放锁
                                                                                                        • 代码演示

                                                                                                          3.生产者消费者

                                                                                                          3.1生产者和消费者模式概述【应用】

                                                                                                          • 概述
                                                                                                            • 生产者消费者模式是一个十分经典的多线程协作的模式,弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻。
                                                                                                              所谓生产者消费者问题,实际上主要是包含了两类线程:
                                                                                                              一类是生产者线程用于生产数据
                                                                                                              一类是消费者线程用于消费数据
                                                                                                              为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库
                                                                                                              生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为
                                                                                                              消费者只需要从共享数据区中去获取数据,并不需要关心生产者的行为
                                                                                                              notion image
                                                                                                          • Object类的等待和唤醒方法
                                                                                                            • 方法名
                                                                                                              说明
                                                                                                              void wait()
                                                                                                              导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法
                                                                                                              void notify()
                                                                                                              唤醒正在等待对象监视器的单个线程
                                                                                                              void notifyAll()
                                                                                                              唤醒正在等待对象监视器的所有线程

                                                                                                          3.2生产者和消费者案例【应用】

                                                                                                          • 案例需求
                                                                                                            • 生产者消费者案例中包含的类:
                                                                                                              奶箱类(Box):定义一个成员变量,表示第x瓶奶,提供存储牛奶和获取牛奶的操作
                                                                                                              生产者类(Producer):实现Runnable接口,重写run()方法,调用存储牛奶的操作
                                                                                                              消费者类(Customer):实现Runnable接口,重写run()方法,调用获取牛奶的操作
                                                                                                              测试类(BoxDemo):里面有main方法,main方法中的代码步骤如下
                                                                                                              ①创建奶箱对象,这是共享数据区域
                                                                                                              ②创建消费者创建生产者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用存储牛奶的操作
                                                                                                              ③对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用获取牛奶的操作
                                                                                                              ④创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
                                                                                                              ⑤启动线程
                                                                                                          • 代码实现

                                                                                                            1.网络编程入门

                                                                                                            1.1 网络编程概述【理解】

                                                                                                            • 计算机网络
                                                                                                              • 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统
                                                                                                            • 网络编程
                                                                                                              • 在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换

                                                                                                            1.2 网络编程三要素【理解】

                                                                                                            • IP地址
                                                                                                              • 要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接收数据的计算机和识别发送的计算机,而IP地址就是这个标识号。也就是设备的标识
                                                                                                            • 端口
                                                                                                              • 网络的通信,本质上是两个应用程序的通信。每台计算机都有很多的应用程序,那么在网络通信时,如何区分这些应用程序呢?如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的应用程序了。也就是应用程序的标识
                                                                                                            • 协议
                                                                                                              • 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换。常见的协议有UDP协议和TCP协议

                                                                                                            1.3 IP地址【理解】

                                                                                                            IP地址:是网络中设备的唯一标识
                                                                                                            • IP地址分为两大类
                                                                                                              • IPv4:是给每个连接在网络上的主机分配一个32bit地址。按照TCP/IP规定,IP地址用二进制来表示,每个IP地址长32bit,也就是4个字节。例如一个采用二进制形式的IP地址是“11000000 10101000 00000001 01000010”,这么长的地址,处理起来也太费劲了。为了方便使用,IP地址经常被写成十进制的形式,中间使用符号“.”分隔不同的字节。于是,上面的IP地址可以表示为“192.168.1.66”。IP地址的这种表示法叫做“点分十进制表示法”,这显然比1和0容易记忆得多
                                                                                                              • IPv6:由于互联网的蓬勃发展,IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。为了扩大地址空间,通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组,分成8组十六进制数,这样就解决了网络地址资源数量不够的问题
                                                                                                            • DOS常用命令:
                                                                                                              • ipconfig:查看本机IP地址
                                                                                                              • ping IP地址:检查网络是否连通
                                                                                                            • 特殊IP地址:
                                                                                                              • 127.0.0.1:是回送地址,可以代表本机地址,一般用来测试使用

                                                                                                            1.4InetAddress【应用】

                                                                                                            InetAddress:此类表示Internet协议(IP)地址
                                                                                                            • 相关方法
                                                                                                              • 方法名
                                                                                                                说明
                                                                                                                static InetAddress getByName(String host)
                                                                                                                确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
                                                                                                                String getHostName()
                                                                                                                获取此IP地址的主机名
                                                                                                                String getHostAddress()
                                                                                                                返回文本显示中的IP地址字符串
                                                                                                            • 代码演示

                                                                                                              1.5端口和协议【理解】

                                                                                                              • 端口
                                                                                                                • 设备上应用程序的唯一标识
                                                                                                              • 端口号
                                                                                                                • 用两个字节表示的整数,它的取值范围是0~65535。其中,0~1023之间的端口号用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败
                                                                                                              • 协议
                                                                                                                • 计算机网络中,连接和通信的规则被称为网络通信协议
                                                                                                              • UDP协议
                                                                                                                • 用户数据报协议(User Datagram Protocol)
                                                                                                                • UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
                                                                                                                • 由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输
                                                                                                                • 例如视频会议通常采用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议
                                                                                                              • TCP协议
                                                                                                                • 传输控制协议 (Transmission Control Protocol)
                                                                                                                • TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”
                                                                                                                • 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠
                                                                                                                  • 第一次握手,客户端向服务器端发出连接请求,等待服务器确认
                                                                                                                    第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求
                                                                                                                    第三次握手,客户端再次向服务器端发送确认信息,确认连接
                                                                                                                • 完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛。例如上传文件、下载文件、浏览网页等

                                                                                                              2.UDP通信程序

                                                                                                              2.1 UDP发送数据【应用】

                                                                                                              • Java中的UDP通信
                                                                                                                • UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念
                                                                                                                • Java提供了DatagramSocket类作为基于UDP协议的Socket
                                                                                                              • 构造方法
                                                                                                                • 方法名
                                                                                                                  说明
                                                                                                                  DatagramSocket()
                                                                                                                  创建数据报套接字并将其绑定到本机地址上的任何可用端口
                                                                                                                  DatagramPacket(byte[] buf,int len,InetAddress add,int port)
                                                                                                                  创建数据包,发送长度为len的数据包到指定主机的指定端口
                                                                                                              • 相关方法
                                                                                                                • 方法名
                                                                                                                  说明
                                                                                                                  void send(DatagramPacket p)
                                                                                                                  发送数据报包
                                                                                                                  void close()
                                                                                                                  关闭数据报套接字
                                                                                                                  void receive(DatagramPacket p)
                                                                                                                  从此套接字接受数据报包
                                                                                                              • 发送数据的步骤
                                                                                                                • 创建发送端的Socket对象(DatagramSocket)
                                                                                                                • 创建数据,并把数据打包
                                                                                                                • 调用DatagramSocket对象的方法发送数据
                                                                                                                • 关闭发送端
                                                                                                              • 代码演示

                                                                                                                2.2UDP接收数据【应用】

                                                                                                                • 接收数据的步骤
                                                                                                                  • 创建接收端的Socket对象(DatagramSocket)
                                                                                                                  • 创建一个数据包,用于接收数据
                                                                                                                  • 调用DatagramSocket对象的方法接收数据
                                                                                                                  • 解析数据包,并把数据在控制台显示
                                                                                                                  • 关闭接收端
                                                                                                                • 构造方法
                                                                                                                  • 方法名
                                                                                                                    说明
                                                                                                                    DatagramPacket(byte[] buf, int len)
                                                                                                                    创建一个DatagramPacket用于接收长度为len的数据包
                                                                                                                • 相关方法
                                                                                                                  • 方法名
                                                                                                                    说明
                                                                                                                    byte[] getData()
                                                                                                                    返回数据缓冲区
                                                                                                                    int getLength()
                                                                                                                    返回要发送的数据的长度或接收的数据的长度
                                                                                                                • 示例代码

                                                                                                                  2.3UDP通信程序练习【应用】

                                                                                                                  • 案例需求
                                                                                                                    • UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
                                                                                                                      UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
                                                                                                                  • 代码实现

                                                                                                                    3.TCP通信程序

                                                                                                                    3.1TCP发送数据【应用】

                                                                                                                    • Java中的TCP通信
                                                                                                                      • Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。
                                                                                                                      • Java为客户端提供了Socket类,为服务器端提供了ServerSocket类
                                                                                                                    • 构造方法
                                                                                                                      • 方法名
                                                                                                                        说明
                                                                                                                        Socket(InetAddress address,int port)
                                                                                                                        创建流套接字并将其连接到指定IP指定端口号
                                                                                                                        Socket(String host, int port)
                                                                                                                        创建流套接字并将其连接到指定主机上的指定端口号
                                                                                                                    • 相关方法
                                                                                                                      • 方法名
                                                                                                                        说明
                                                                                                                        InputStream getInputStream()
                                                                                                                        返回此套接字的输入流
                                                                                                                        OutputStream getOutputStream()
                                                                                                                        返回此套接字的输出流
                                                                                                                    • 示例代码

                                                                                                                      3.2TCP接收数据【应用】

                                                                                                                      • 构造方法
                                                                                                                        • 方法名
                                                                                                                          说明
                                                                                                                          ServletSocket(int port)
                                                                                                                          创建绑定到指定端口的服务器套接字
                                                                                                                      • 相关方法
                                                                                                                        • 方法名
                                                                                                                          说明
                                                                                                                          Socket accept()
                                                                                                                          监听要连接到此的套接字并接受它
                                                                                                                      • 示例代码

                                                                                                                        3.3TCP通信程序练习【应用】

                                                                                                                        • 案例需求
                                                                                                                          • 客户端:发送数据,接受服务器反馈
                                                                                                                            服务器:收到消息后给出反馈
                                                                                                                        • 案例分析
                                                                                                                          • 客户端创建对象,使用输出流输出数据
                                                                                                                          • 服务端创建对象,使用输入流接受数据
                                                                                                                          • 服务端使用输出流给出反馈数据
                                                                                                                          • 客户端使用输入流接受反馈数据
                                                                                                                        • 代码实现

                                                                                                                          3.4TCP通信程序练习【应用】

                                                                                                                          • 案例需求
                                                                                                                            • 客户端:数据来自于键盘录入, 直到输入的数据是886,发送数据结束
                                                                                                                              服务端:接收到数据在控制台输出
                                                                                                                          • 案例分析
                                                                                                                            • 客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止
                                                                                                                            • 服务端创建对象,使用输入流按行循环接受数据,直到接受到null为止
                                                                                                                          • 代码实现

                                                                                                                            3.5TCP通信程序练习【应用】

                                                                                                                            • 案例需求
                                                                                                                              • 客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
                                                                                                                                服务端:接受到的数据写入文本文件中
                                                                                                                            • 案例分析
                                                                                                                              • 客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止
                                                                                                                              • 服务端创建对象,创建输出流对象指向文件,每接受一行数据后使用输出流输出到文件中,直到接受到null为止
                                                                                                                            • 代码实现

                                                                                                                              3.6TCP通信程序练习【应用】

                                                                                                                              • 案例需求
                                                                                                                                • 客户端:数据来自于文本文件
                                                                                                                                  服务器:接收到的数据写入文本文件
                                                                                                                              • 案例分析
                                                                                                                                • 创建客户端,创建输入流对象指向文件,从文件循环读取数据,每读取一行就使用输出流给服务器输出一行
                                                                                                                                • 创建服务端,创建输出流对象指向文件,从客户端接受数据,每接受一行就给文件中输出一行
                                                                                                                              • 代码实现

                                                                                                                                3.7TCP通信程序练习【应用】

                                                                                                                                • 案例需求
                                                                                                                                  • 客户端:数据来自于文本文件,接收服务器反馈
                                                                                                                                    服务器:接收到的数据写入文本文件,给出反馈
                                                                                                                                • 案例分析
                                                                                                                                  • 创建客户端对象,创建输入流对象指向文件,每读入一行数据就给服务器输出一行数据,输出结束后使用shutdownOutput()方法告知服务端传输结束
                                                                                                                                  • 创建服务器对象,创建输出流对象指向文件,每接受一行数据就使用输出流输出到文件中,传输结束后。使用输出流给客户端反馈信息
                                                                                                                                  • 客户端接受服务端的回馈信息
                                                                                                                                • 相关方法
                                                                                                                                  • 方法名
                                                                                                                                    说明
                                                                                                                                    void shutdownInput()
                                                                                                                                    将此套接字的输入流放置在“流的末尾”
                                                                                                                                    void shutdownOutput()
                                                                                                                                    禁止用此套接字的输出流
                                                                                                                                • 代码实现

                                                                                                                                  3.8TCP通信程序练习【应用】

                                                                                                                                  • 案例需求
                                                                                                                                    • 客户端:数据来自于文本文件,接收服务器反馈
                                                                                                                                      服务器:接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
                                                                                                                                  • 案例分析
                                                                                                                                    • 创建客户端对象,创建输入流对象指向文件,每读入一行数据就给服务器输出一行数据,输出结束后使用shutdownOutput()方法告知服务端传输结束
                                                                                                                                    • 创建多线程类,在run()方法中读取客户端发送的数据,为了防止文件重名,使用计数器给文件名编号,接受结束后使用输出流给客户端发送反馈信息。
                                                                                                                                    • 创建服务端对象,每监听到一个客户端则开启一个新的线程接受数据。
                                                                                                                                    • 客户端接受服务端的回馈信息
                                                                                                                                  • 代码实现

                                                                                                                                    1.Lambda表达式

                                                                                                                                    1.1体验Lambda表达式【理解】

                                                                                                                                    • 案例需求
                                                                                                                                      • 启动一个线程,在控制台输出一句话:多线程程序启动了
                                                                                                                                    • 实现方式一
                                                                                                                                      • 实现步骤
                                                                                                                                        • 定义一个类MyRunnable实现Runnable接口,重写run()方法
                                                                                                                                        • 创建MyRunnable类的对象
                                                                                                                                        • 创建Thread类的对象,把MyRunnable的对象作为构造参数传递
                                                                                                                                        • 启动线程
                                                                                                                                    • 实现方式二
                                                                                                                                      • 匿名内部类的方式改进
                                                                                                                                    • 实现方式三
                                                                                                                                      • Lambda表达式的方式改进
                                                                                                                                    • 代码演示
                                                                                                                                      • 函数式编程思想概述
                                                                                                                                        • 函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”
                                                                                                                                          而我们要学习的Lambda表达式就是函数式思想的体现

                                                                                                                                      1.2Lambda表达式的标准格式【理解】

                                                                                                                                      • 格式:
                                                                                                                                        • (形式参数) -> {代码块}
                                                                                                                                        • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
                                                                                                                                        • >:由英文中画线和大于符号组成,固定写法。代表指向动作
                                                                                                                                        • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
                                                                                                                                      • 组成Lambda表达式的三要素:
                                                                                                                                        • 形式参数,箭头,代码块

                                                                                                                                      1.3Lambda表达式练习1【应用】

                                                                                                                                      • Lambda表达式的使用前提
                                                                                                                                        • 有一个接口
                                                                                                                                        • 接口中有且仅有一个抽象方法
                                                                                                                                      • 练习描述
                                                                                                                                        • 无参无返回值抽象方法的练习
                                                                                                                                      • 操作步骤
                                                                                                                                        • 定义一个接口(Eatable),里面定义一个抽象方法:void eat();
                                                                                                                                        • 定义一个测试类(EatableDemo),在测试类中提供两个方法
                                                                                                                                          • 一个方法是:useEatable(Eatable e)
                                                                                                                                          • 一个方法是主方法,在主方法中调用useEatable方法
                                                                                                                                      • 示例代码

                                                                                                                                        1.4Lambda表达式练习2【应用】

                                                                                                                                        • 练习描述
                                                                                                                                          • 有参无返回值抽象方法的练习
                                                                                                                                        • 操作步骤
                                                                                                                                          • 定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);
                                                                                                                                          • 定义一个测试类(FlyableDemo),在测试类中提供两个方法
                                                                                                                                            • 一个方法是:useFlyable(Flyable f)
                                                                                                                                            • 一个方法是主方法,在主方法中调用useFlyable方法
                                                                                                                                        • 示例代码

                                                                                                                                          1.5Lambda表达式练习3【应用】

                                                                                                                                          • 练习描述
                                                                                                                                            • 有参有返回值抽象方法的练习
                                                                                                                                          • 操作步骤
                                                                                                                                            • 定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);
                                                                                                                                            • 定义一个测试类(AddableDemo),在测试类中提供两个方法
                                                                                                                                              • 一个方法是:useAddable(Addable a)
                                                                                                                                              • 一个方法是主方法,在主方法中调用useAddable方法
                                                                                                                                          • 示例代码

                                                                                                                                            1.6Lambda表达式的省略模式【应用】

                                                                                                                                            • 省略的规则
                                                                                                                                              • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
                                                                                                                                              • 如果参数有且仅有一个,那么小括号可以省略
                                                                                                                                              • 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
                                                                                                                                            • 代码演示

                                                                                                                                              1.7Lambda表达式的注意事项【理解】

                                                                                                                                              • 使用Lambda必须要有接口,并且要求接口中有且仅有一个抽象方法
                                                                                                                                              • 必须有上下文环境,才能推导出Lambda对应的接口
                                                                                                                                                • 根据局部变量的赋值得知Lambda对应的接口
                                                                                                                                                  • Runnable r = () -> System.out.println("Lambda表达式");
                                                                                                                                                • 根据调用方法的参数得知Lambda对应的接口
                                                                                                                                                  • new Thread(() -> System.out.println("Lambda表达式")).start();

                                                                                                                                              1.8Lambda表达式和匿名内部类的区别【理解】

                                                                                                                                              • 所需类型不同
                                                                                                                                                • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
                                                                                                                                                • Lambda表达式:只能是接口
                                                                                                                                              • 使用限制不同
                                                                                                                                                • 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
                                                                                                                                                • 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
                                                                                                                                              • 实现原理不同
                                                                                                                                                • 匿名内部类:编译之后,产生一个单独的.class字节码文件
                                                                                                                                                • Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

                                                                                                                                              2.接口组成更新

                                                                                                                                              2.1接口组成更新概述【理解】

                                                                                                                                              • 常量
                                                                                                                                                • public static final
                                                                                                                                              • 抽象方法
                                                                                                                                                • public abstract
                                                                                                                                              • 默认方法(Java 8)
                                                                                                                                              • 静态方法(Java 8)
                                                                                                                                              • 私有方法(Java 9)

                                                                                                                                              2.2接口中默认方法【应用】

                                                                                                                                              • 格式
                                                                                                                                                • public default 返回值类型 方法名(参数列表) { }
                                                                                                                                              • 范例
                                                                                                                                                • 注意事项
                                                                                                                                                  • 默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字
                                                                                                                                                  • public可以省略,default不能省略

                                                                                                                                                2.3接口中静态方法【应用】

                                                                                                                                                • 格式
                                                                                                                                                  • public static 返回值类型 方法名(参数列表) { }
                                                                                                                                                • 范例
                                                                                                                                                  • 注意事项
                                                                                                                                                    • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
                                                                                                                                                    • public可以省略,static不能省略

                                                                                                                                                  2.4接口中私有方法【应用】

                                                                                                                                                  • 私有方法产生原因
                                                                                                                                                    • Java 9中新增了带方法体的私有方法,这其实在Java 8中就埋下了伏笔:Java 8允许在接口中定义带方法体的默认方法和静态方法。这样可能就会引发一个问题:当两个默认方法或者静态方法中包含一段相同的代码实现时,程序必然考虑将这段实现代码抽取成一个共性方法,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java 9增加私有方法的必然性
                                                                                                                                                  • 定义格式
                                                                                                                                                    • 格式1
                                                                                                                                                      • private 返回值类型 方法名(参数列表) { }
                                                                                                                                                    • 范例1
                                                                                                                                                      • 格式2
                                                                                                                                                        • private static 返回值类型 方法名(参数列表) { }
                                                                                                                                                      • 范例2
                                                                                                                                                      • 注意事项
                                                                                                                                                        • 默认方法可以调用私有的静态方法和非静态方法
                                                                                                                                                        • 静态方法只能调用私有的静态方法

                                                                                                                                                      3.方法引用

                                                                                                                                                      3.1体验方法引用【理解】

                                                                                                                                                      • 方法引用的出现原因
                                                                                                                                                        • 在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作
                                                                                                                                                          那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?答案肯定是没有必要
                                                                                                                                                          那我们又是如何使用已经存在的方案的呢?
                                                                                                                                                          这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案
                                                                                                                                                      • 代码演示

                                                                                                                                                        3.2方法引用符【理解】

                                                                                                                                                        • 方法引用符
                                                                                                                                                          • :: 该符号为引用运算符,而它所在的表达式被称为方法引用
                                                                                                                                                        • 推导与省略
                                                                                                                                                          • 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
                                                                                                                                                          • 如果使用方法引用,也是同样可以根据上下文进行推导
                                                                                                                                                          • 方法引用是Lambda的孪生兄弟

                                                                                                                                                        3.3引用类方法【应用】

                                                                                                                                                        引用类方法,其实就是引用类的静态方法
                                                                                                                                                        • 格式
                                                                                                                                                          • 类名::静态方法
                                                                                                                                                        • 范例
                                                                                                                                                          • Integer::parseInt
                                                                                                                                                            Integer类的方法:public static int parseInt(String s) 将此String转换为int类型数据
                                                                                                                                                        • 练习描述
                                                                                                                                                          • 定义一个接口(Converter),里面定义一个抽象方法 int convert(String s);
                                                                                                                                                          • 定义一个测试类(ConverterDemo),在测试类中提供两个方法
                                                                                                                                                            • 一个方法是:useConverter(Converter c)
                                                                                                                                                            • 一个方法是主方法,在主方法中调用useConverter方法
                                                                                                                                                        • 代码演示
                                                                                                                                                          • 使用说明
                                                                                                                                                            • Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数

                                                                                                                                                          3.4引用对象的实例方法【应用】

                                                                                                                                                          引用对象的实例方法,其实就引用类中的成员方法
                                                                                                                                                          • 格式
                                                                                                                                                            • 对象::成员方法
                                                                                                                                                          • 范例
                                                                                                                                                            • "HelloWorld"::toUpperCase
                                                                                                                                                              String类中的方法:public String toUpperCase() 将此String所有字符转换为大写
                                                                                                                                                          • 练习描述
                                                                                                                                                            • 定义一个类(PrintString),里面定义一个方法
                                                                                                                                                              • public void printUpper(String s):把字符串参数变成大写的数据,然后在控制台输出
                                                                                                                                                            • 定义一个接口(Printer),里面定义一个抽象方法
                                                                                                                                                              • void printUpperCase(String s)
                                                                                                                                                            • 定义一个测试类(PrinterDemo),在测试类中提供两个方法
                                                                                                                                                              • 一个方法是:usePrinter(Printer p)
                                                                                                                                                              • 一个方法是主方法,在主方法中调用usePrinter方法
                                                                                                                                                          • 代码演示
                                                                                                                                                            • 使用说明
                                                                                                                                                              • Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数

                                                                                                                                                            3.5引用类的实例方法【应用】

                                                                                                                                                            引用类的实例方法,其实就是引用类中的成员方法
                                                                                                                                                            • 格式
                                                                                                                                                              • 类名::成员方法
                                                                                                                                                            • 范例
                                                                                                                                                              • String::substring
                                                                                                                                                                public String substring(int beginIndex,int endIndex)
                                                                                                                                                                从beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度为endIndex-beginIndex
                                                                                                                                                            • 练习描述
                                                                                                                                                              • 定义一个接口(MyString),里面定义一个抽象方法:
                                                                                                                                                                • String mySubString(String s,int x,int y);
                                                                                                                                                              • 定义一个测试类(MyStringDemo),在测试类中提供两个方法
                                                                                                                                                                • 一个方法是:useMyString(MyString my)
                                                                                                                                                                • 一个方法是主方法,在主方法中调用useMyString方法
                                                                                                                                                            • 代码演示
                                                                                                                                                              • 使用说明
                                                                                                                                                                • Lambda表达式被类的实例方法替代的时候 第一个参数作为调用者 后面的参数全部传递给该方法作为参数

                                                                                                                                                              3.6引用构造器【应用】

                                                                                                                                                              引用构造器,其实就是引用构造方法
                                                                                                                                                              • l格式
                                                                                                                                                                • 类名::new
                                                                                                                                                              • 范例
                                                                                                                                                                • Student::new
                                                                                                                                                              • 练习描述
                                                                                                                                                                • 定义一个类(Student),里面有两个成员变量(name,age)
                                                                                                                                                                  • 并提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法
                                                                                                                                                                • 定义一个接口(StudentBuilder),里面定义一个抽象方法
                                                                                                                                                                  • Student build(String name,int age);
                                                                                                                                                                • 定义一个测试类(StudentDemo),在测试类中提供两个方法
                                                                                                                                                                  • 一个方法是:useStudentBuilder(StudentBuilder s)
                                                                                                                                                                  • 一个方法是主方法,在主方法中调用useStudentBuilder方法
                                                                                                                                                              • 代码演示
                                                                                                                                                                • 使用说明
                                                                                                                                                                  • Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数

                                                                                                                                                                1.函数式接口

                                                                                                                                                                1.1函数式接口概述【理解】

                                                                                                                                                                • 概念
                                                                                                                                                                  • 有且仅有一个抽象方法的接口
                                                                                                                                                                • 如何检测一个接口是不是函数式接口
                                                                                                                                                                  • @FunctionalInterface
                                                                                                                                                                    放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
                                                                                                                                                                • 注意事项
                                                                                                                                                                  • 我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。但是,建议加上该注解

                                                                                                                                                                1.2函数式接口作为方法的参数【应用】

                                                                                                                                                                • 需求描述
                                                                                                                                                                  • 定义一个类(RunnableDemo),在类中提供两个方法
                                                                                                                                                                    一个方法是:startThread(Runnable r) 方法参数Runnable是一个函数式接口
                                                                                                                                                                    一个方法是主方法,在主方法中调用startThread方法
                                                                                                                                                                • 代码演示

                                                                                                                                                                  1.3函数式接口作为方法的返回值【应用】

                                                                                                                                                                  • 需求描述
                                                                                                                                                                    • 定义一个类(ComparatorDemo),在类中提供两个方法
                                                                                                                                                                      一个方法是:Comparator<String> getComparator() 方法返回值Comparator是一个函数式接口
                                                                                                                                                                      一个方法是主方法,在主方法中调用getComparator方法
                                                                                                                                                                  • 代码演示

                                                                                                                                                                    1.4常用函数式接口之Supplier【应用】

                                                                                                                                                                    • Supplier接口
                                                                                                                                                                      • Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用。
                                                                                                                                                                    • 常用方法
                                                                                                                                                                      • 只有一个无参的方法
                                                                                                                                                                        方法名
                                                                                                                                                                        说明
                                                                                                                                                                        T get()
                                                                                                                                                                        按照某种实现逻辑(由Lambda表达式实现)返回一个数据
                                                                                                                                                                    • 代码演示

                                                                                                                                                                      1.5Supplier接口练习之获取最大值【应用】

                                                                                                                                                                      • 案例需求
                                                                                                                                                                        • 定义一个类(SupplierTest),在类中提供两个方法
                                                                                                                                                                          一个方法是:int getMax(Supplier<Integer> sup) 用于返回一个int数组中的最大值
                                                                                                                                                                          一个方法是主方法,在主方法中调用getMax方法
                                                                                                                                                                      • 示例代码

                                                                                                                                                                        1.6常用函数式接口之Consumer【应用】

                                                                                                                                                                        • Consumer接口
                                                                                                                                                                          • Consumer<T>接口也被称为消费型接口,它消费的数据的数据类型由泛型指定
                                                                                                                                                                        • 常用方法
                                                                                                                                                                          • Consumer<T>:包含两个方法
                                                                                                                                                                            方法名
                                                                                                                                                                            说明
                                                                                                                                                                            void accept(T t)
                                                                                                                                                                            对给定的参数执行此操作
                                                                                                                                                                            default Consumer<T> andThen(Consumer after)
                                                                                                                                                                            返回一个组合的Consumer,依次执行此操作,然后执行 after操作
                                                                                                                                                                        • 代码演示

                                                                                                                                                                          1.7Consumer接口练习之按要求打印信息【应用】

                                                                                                                                                                          • 案例需求
                                                                                                                                                                            • String[] strArray = {"林青霞,30", "张曼玉,35", "王祖贤,33"};
                                                                                                                                                                              字符串数组中有多条信息,请按照格式:“姓名:XX,年龄:XX"的格式将信息打印出来
                                                                                                                                                                              要求:
                                                                                                                                                                              把打印姓名的动作作为第一个Consumer接口的Lambda实例
                                                                                                                                                                              把打印年龄的动作作为第二个Consumer接口的Lambda实例
                                                                                                                                                                              将两个Consumer接口按照顺序组合到一起使用
                                                                                                                                                                          • 示例代码

                                                                                                                                                                            1.8常用函数式接口之Predicate【应用】

                                                                                                                                                                            • Predicate接口
                                                                                                                                                                              • Predicate<T>接口通常用于判断参数是否满足指定的条件
                                                                                                                                                                            • 常用方法
                                                                                                                                                                              • 方法名
                                                                                                                                                                                说明
                                                                                                                                                                                boolean test(T t)
                                                                                                                                                                                对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
                                                                                                                                                                                default Predicate<T> negate()
                                                                                                                                                                                返回一个逻辑的否定,对应逻辑非
                                                                                                                                                                                default Predicate<T> and(Predicate other)
                                                                                                                                                                                返回一个组合判断,对应短路与
                                                                                                                                                                                default Predicate<T> or(Predicate other)
                                                                                                                                                                                返回一个组合判断,对应短路或
                                                                                                                                                                            • 代码演示

                                                                                                                                                                              1.9Predicate接口练习之筛选满足条件数据【应用】

                                                                                                                                                                              • 练习描述
                                                                                                                                                                                • String[] strArray = {"林青霞,30", "柳岩,34", "张曼玉,35", "貂蝉,31", "王祖贤,33"};
                                                                                                                                                                                • 字符串数组中有多条信息,请通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,并遍历ArrayList集合
                                                                                                                                                                                • 同时满足如下要求:姓名长度大于2;年龄大于33
                                                                                                                                                                              • 分析
                                                                                                                                                                                • 有两个判断条件,所以需要使用两个Predicate接口,对条件进行判断
                                                                                                                                                                                • 必须同时满足两个条件,所以可以使用and方法连接两个判断条件
                                                                                                                                                                              • 示例代码

                                                                                                                                                                                1.10常用函数式接口之Function【应用】

                                                                                                                                                                                • Function接口
                                                                                                                                                                                  • Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
                                                                                                                                                                                • 常用方法
                                                                                                                                                                                  • 方法名
                                                                                                                                                                                    说明
                                                                                                                                                                                    R apply(T t)
                                                                                                                                                                                    将此函数应用于给定的参数
                                                                                                                                                                                    default <V> Function andThen(Function after)
                                                                                                                                                                                    返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
                                                                                                                                                                                • 代码演示

                                                                                                                                                                                  1.11Function接口练习之按照指定要求操作数据【应用】

                                                                                                                                                                                  • 练习描述
                                                                                                                                                                                    • String s = "林青霞,30";
                                                                                                                                                                                    • 请按照我指定的要求进行操作:
                                                                                                                                                                                      • 1:将字符串截取得到数字年龄部分
                                                                                                                                                                                        2:将上一步的年龄字符串转换成为int类型的数据
                                                                                                                                                                                        3:将上一步的int数据加70,得到一个int结果,在控制台输出
                                                                                                                                                                                    • 请通过Function接口来实现函数拼接
                                                                                                                                                                                  • 示例代码

                                                                                                                                                                                    2.Strem流

                                                                                                                                                                                    2.1体验Stream流【理解】

                                                                                                                                                                                    • 案例需求
                                                                                                                                                                                      • 按照下面的要求完成集合的创建和遍历
                                                                                                                                                                                      • 创建一个集合,存储多个字符串元素
                                                                                                                                                                                      • 把集合中所有以"张"开头的元素存储到一个新的集合
                                                                                                                                                                                      • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
                                                                                                                                                                                      • 遍历上一步得到的集合
                                                                                                                                                                                    • 原始方式示例代码
                                                                                                                                                                                      • 使用Stream流示例代码
                                                                                                                                                                                        • Stream流的好处
                                                                                                                                                                                          • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
                                                                                                                                                                                          • Stream流把真正的函数式编程风格引入到Java中

                                                                                                                                                                                        2.2Stream流的常见生成方式【应用】

                                                                                                                                                                                        • Stream流的思想
                                                                                                                                                                                          • notion image
                                                                                                                                                                                        • 生成Stream流的方式
                                                                                                                                                                                          • Collection体系集合
                                                                                                                                                                                            • 使用默认方法stream()生成流, default Stream<E> stream()
                                                                                                                                                                                          • Map体系集合
                                                                                                                                                                                            • 把Map转成Set集合,间接的生成流
                                                                                                                                                                                          • 数组
                                                                                                                                                                                            • 通过Stream接口的静态方法of(T... values)生成流
                                                                                                                                                                                        • 代码演示

                                                                                                                                                                                          2.3Stream流中间操作方法【应用】

                                                                                                                                                                                          • 概念
                                                                                                                                                                                            • 中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作。
                                                                                                                                                                                          • 常见方法
                                                                                                                                                                                            • 方法名
                                                                                                                                                                                              说明
                                                                                                                                                                                              Stream<T> filter(Predicate predicate)
                                                                                                                                                                                              用于对流中的数据进行过滤
                                                                                                                                                                                              Stream<T> limit(long maxSize)
                                                                                                                                                                                              返回此流中的元素组成的流,截取前指定参数个数的数据
                                                                                                                                                                                              Stream<T> skip(long n)
                                                                                                                                                                                              跳过指定参数个数的数据,返回由该流的剩余元素组成的流
                                                                                                                                                                                              static <T> Stream<T> concat(Stream a, Stream b)
                                                                                                                                                                                              合并a和b两个流为一个流
                                                                                                                                                                                              Stream<T> distinct()
                                                                                                                                                                                              返回由该流的不同元素(根据Object.equals(Object) )组成的流
                                                                                                                                                                                              Stream<T> sorted()
                                                                                                                                                                                              返回由此流的元素组成的流,根据自然顺序排序
                                                                                                                                                                                              Stream<T> sorted(Comparator comparator)
                                                                                                                                                                                              返回由该流的元素组成的流,根据提供的Comparator进行排序
                                                                                                                                                                                              <R> Stream<R> map(Function mapper)
                                                                                                                                                                                              返回由给定函数应用于此流的元素的结果组成的流
                                                                                                                                                                                              IntStream mapToInt(ToIntFunction mapper)
                                                                                                                                                                                              返回一个IntStream其中包含将给定函数应用于此流的元素的结果
                                                                                                                                                                                          • filter代码演示
                                                                                                                                                                                            • limit&skip代码演示
                                                                                                                                                                                              • concat&distinct代码演示
                                                                                                                                                                                                • sorted代码演示
                                                                                                                                                                                                  • map&mapToInt代码演示

                                                                                                                                                                                                    2.4Stream流终结操作方法【应用】

                                                                                                                                                                                                    • 概念
                                                                                                                                                                                                      • 终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作。
                                                                                                                                                                                                    • 常见方法
                                                                                                                                                                                                      • 方法名
                                                                                                                                                                                                        说明
                                                                                                                                                                                                        void forEach(Consumer action)
                                                                                                                                                                                                        对此流的每个元素执行操作
                                                                                                                                                                                                        long count()
                                                                                                                                                                                                        返回此流中的元素数
                                                                                                                                                                                                    • 代码演示

                                                                                                                                                                                                      2.5Stream流综合练习【应用】

                                                                                                                                                                                                      • 案例需求
                                                                                                                                                                                                        • 现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
                                                                                                                                                                                                        • 男演员只要名字为3个字的前三人
                                                                                                                                                                                                        • 女演员只要姓林的,并且不要第一个
                                                                                                                                                                                                        • 把过滤后的男演员姓名和女演员姓名合并到一起
                                                                                                                                                                                                        • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
                                                                                                                                                                                                        • 演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
                                                                                                                                                                                                      • 代码实现

                                                                                                                                                                                                        2.6Stream流的收集操作【应用】

                                                                                                                                                                                                        • 概念
                                                                                                                                                                                                          • 对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中。
                                                                                                                                                                                                        • 常用方法
                                                                                                                                                                                                          • 方法名
                                                                                                                                                                                                            说明
                                                                                                                                                                                                            R collect(Collector collector)
                                                                                                                                                                                                            把结果收集到集合中
                                                                                                                                                                                                        • 工具类Collectors提供了具体的收集方式
                                                                                                                                                                                                          • 方法名
                                                                                                                                                                                                            说明
                                                                                                                                                                                                            public static <T> Collector toList()
                                                                                                                                                                                                            把元素收集到List集合中
                                                                                                                                                                                                            public static <T> Collector toSet()
                                                                                                                                                                                                            把元素收集到Set集合中
                                                                                                                                                                                                            public static Collector toMap(Function keyMapper,Function valueMapper)
                                                                                                                                                                                                            把元素收集到Map集合中
                                                                                                                                                                                                        • 代码演示

                                                                                                                                                                                                          1.类加载器

                                                                                                                                                                                                          1.1类加载【理解】

                                                                                                                                                                                                          • 类加载的描述
                                                                                                                                                                                                            • 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者类初始化
                                                                                                                                                                                                          • 类的加载
                                                                                                                                                                                                            • 就是指将class文件读入内存,并为之创建一个 java.lang.Class 对象
                                                                                                                                                                                                            • 任何类被使用时,系统都会为之建立一个 java.lang.Class 对象
                                                                                                                                                                                                          • 类的连接
                                                                                                                                                                                                            • 验证阶段:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致
                                                                                                                                                                                                            • 准备阶段:负责为类的类变量分配内存,并设置默认初始化值
                                                                                                                                                                                                            • 解析阶段:将类的二进制数据中的符号引用替换为直接引用
                                                                                                                                                                                                          • 类的初始化
                                                                                                                                                                                                            • 在该阶段,主要就是对类变量进行初始化
                                                                                                                                                                                                          • 类的初始化步骤
                                                                                                                                                                                                            • 假如类还未被加载和连接,则程序先加载并连接该类
                                                                                                                                                                                                            • 假如该类的直接父类还未被初始化,则先初始化其直接父类
                                                                                                                                                                                                            • 假如类中有初始化语句,则系统依次执行这些初始化语句
                                                                                                                                                                                                            • 注意:在执行第2个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3
                                                                                                                                                                                                          • 类的初始化时机
                                                                                                                                                                                                            • 创建类的实例
                                                                                                                                                                                                            • 调用类的类方法
                                                                                                                                                                                                            • 访问类或者接口的类变量,或者为该类变量赋值
                                                                                                                                                                                                            • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
                                                                                                                                                                                                            • 初始化某个类的子类
                                                                                                                                                                                                            • 直接使用java.exe命令来运行某个主类

                                                                                                                                                                                                          1.2类加载器【理解】

                                                                                                                                                                                                          1.2.1类加载器的作用

                                                                                                                                                                                                          • 负责将.class文件加载到内存中,并为之生成对应的 java.lang.Class 对象。虽然我们不用过分关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行!

                                                                                                                                                                                                          1.2.2JVM的类加载机制

                                                                                                                                                                                                          • 全盘负责:就是当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入
                                                                                                                                                                                                          • 父类委托:就是当一个类加载器负责加载某个Class时,先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类
                                                                                                                                                                                                          • 缓存机制:保证所有加载过的Class都会被缓存,当程序需要使用某个Class对象时,类加载器先从缓存区中搜索该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存储到缓存区

                                                                                                                                                                                                          1.2.3Java中的内置类加载器

                                                                                                                                                                                                          • Bootstrap class loader:它是虚拟机的内置类加载器,通常表示为null ,并且没有父null
                                                                                                                                                                                                          • Platform class loader:平台类加载器可以看到所有平台类 ,平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类
                                                                                                                                                                                                          • System class loader:它也被称为应用程序类加载器 ,与平台类加载器不同。 系统类加载器通常用于定义应用程序类路径,模块路径和JDK特定工具上的类
                                                                                                                                                                                                          • 类加载器的继承关系:System的父加载器为Platform,而Platform的父加载器为Bootstrap

                                                                                                                                                                                                          1.2.4ClassLoader 中的两个方法

                                                                                                                                                                                                          • 方法分类
                                                                                                                                                                                                            • 方法名
                                                                                                                                                                                                              说明
                                                                                                                                                                                                              static ClassLoader getSystemClassLoader()
                                                                                                                                                                                                              返回用于委派的系统类加载器
                                                                                                                                                                                                              ClassLoader getParent()
                                                                                                                                                                                                              返回父类加载器进行委派
                                                                                                                                                                                                          • 示例代码

                                                                                                                                                                                                            2.反射

                                                                                                                                                                                                            2.1反射的概述【理解】

                                                                                                                                                                                                            • 是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展

                                                                                                                                                                                                            2.2获取Class类对象的三种方式【应用】

                                                                                                                                                                                                            2.2.1三种方式分类

                                                                                                                                                                                                            • 类名.class属性
                                                                                                                                                                                                            • 对象名.getClass()方法
                                                                                                                                                                                                            • Class.forName(全类名)方法

                                                                                                                                                                                                            2.2.2示例代码

                                                                                                                                                                                                            2.3反射获取构造方法并使用【应用】

                                                                                                                                                                                                            2.3.1Class类获取构造方法对象的方法

                                                                                                                                                                                                            • 方法分类
                                                                                                                                                                                                              • 方法名
                                                                                                                                                                                                                说明
                                                                                                                                                                                                                Constructor<?>[] getConstructors()
                                                                                                                                                                                                                返回所有公共构造方法对象的数组
                                                                                                                                                                                                                Constructor<?>[] getDeclaredConstructors()
                                                                                                                                                                                                                返回所有构造方法对象的数组
                                                                                                                                                                                                                Constructor<T> getConstructor(Class<?>... parameterTypes)
                                                                                                                                                                                                                返回单个公共构造方法对象
                                                                                                                                                                                                                Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
                                                                                                                                                                                                                返回单个构造方法对象
                                                                                                                                                                                                            • 示例代码

                                                                                                                                                                                                              2.3.2Constructor类用于创建对象的方法

                                                                                                                                                                                                              方法名
                                                                                                                                                                                                              说明
                                                                                                                                                                                                              T newInstance(Object...initargs)
                                                                                                                                                                                                              根据指定的构造方法创建对象

                                                                                                                                                                                                              2.4反射获取构造方法并使用练习1【应用】

                                                                                                                                                                                                              • 案例需求
                                                                                                                                                                                                                • 通过反射获取公共的构造方法并创建对象
                                                                                                                                                                                                              • 代码实现
                                                                                                                                                                                                                • 学生类
                                                                                                                                                                                                                  • 测试类

                                                                                                                                                                                                                  2.5反射获取构造方法并使用练习2【应用】

                                                                                                                                                                                                                  • 案例需求
                                                                                                                                                                                                                    • 通过反射获取私有构造方法并创建对象
                                                                                                                                                                                                                  • 代码实现
                                                                                                                                                                                                                    • 学生类:参见上方学生类
                                                                                                                                                                                                                    • 测试类

                                                                                                                                                                                                                    2.6反射获取成员变量并使用【应用】

                                                                                                                                                                                                                    2.6.1Class类获取成员变量对象的方法

                                                                                                                                                                                                                    • 方法分类
                                                                                                                                                                                                                      • 方法名
                                                                                                                                                                                                                        说明
                                                                                                                                                                                                                        Field[] getFields()
                                                                                                                                                                                                                        返回所有公共成员变量对象的数组
                                                                                                                                                                                                                        Field[] getDeclaredFields()
                                                                                                                                                                                                                        返回所有成员变量对象的数组
                                                                                                                                                                                                                        Field getField(String name)
                                                                                                                                                                                                                        返回单个公共成员变量对象
                                                                                                                                                                                                                        Field getDeclaredField(String name)
                                                                                                                                                                                                                        返回单个成员变量对象
                                                                                                                                                                                                                    • 示例代码

                                                                                                                                                                                                                      2.6.2Field类用于给成员变量赋值的方法

                                                                                                                                                                                                                      方法名
                                                                                                                                                                                                                      说明
                                                                                                                                                                                                                      voidset(Object obj,Object value)
                                                                                                                                                                                                                      给obj对象的成员变量赋值为value

                                                                                                                                                                                                                      2.7反射获取成员变量并使用练习【应用】

                                                                                                                                                                                                                      • 案例需求
                                                                                                                                                                                                                        • 通过反射获取成员变量并赋值
                                                                                                                                                                                                                      • 代码实现
                                                                                                                                                                                                                        • 学生类:参见上方学生类
                                                                                                                                                                                                                        • 测试类

                                                                                                                                                                                                                        2.8反射获取成员方法并使用【应用】

                                                                                                                                                                                                                        2.8.1Class类获取成员方法对象的方法

                                                                                                                                                                                                                        • 方法分类
                                                                                                                                                                                                                          • 方法名
                                                                                                                                                                                                                            说明
                                                                                                                                                                                                                            Method[] getMethods()
                                                                                                                                                                                                                            返回所有公共成员方法对象的数组,包括继承的
                                                                                                                                                                                                                            Method[] getDeclaredMethods()
                                                                                                                                                                                                                            返回所有成员方法对象的数组,不包括继承的
                                                                                                                                                                                                                            Method getMethod(String name, Class<?>... parameterTypes)
                                                                                                                                                                                                                            返回单个公共成员方法对象
                                                                                                                                                                                                                            Method getDeclaredMethod(String name, Class<?>... parameterTypes)
                                                                                                                                                                                                                            返回单个成员方法对象
                                                                                                                                                                                                                        • 示例代码

                                                                                                                                                                                                                          2.8.2Method类用于执行方法的方法

                                                                                                                                                                                                                          方法名
                                                                                                                                                                                                                          说明
                                                                                                                                                                                                                          Objectinvoke(Object obj,Object... args)
                                                                                                                                                                                                                          调用obj对象的成员方法,参数是args,返回值是Object类型

                                                                                                                                                                                                                          2.9反射获取成员方法并使用练习【应用】

                                                                                                                                                                                                                          • 案例需求
                                                                                                                                                                                                                            • 通过反射获取成员方法并调用
                                                                                                                                                                                                                          • 代码实现
                                                                                                                                                                                                                            • 学生类:参见上方学生类
                                                                                                                                                                                                                            • 测试类

                                                                                                                                                                                                                            2.10反射的案例【应用】

                                                                                                                                                                                                                            2.10.1反射练习之越过泛型检查

                                                                                                                                                                                                                            • 案例需求
                                                                                                                                                                                                                              • 通过反射技术,向一个泛型为Integer的集合中添加一些字符串数据
                                                                                                                                                                                                                            • 代码实现

                                                                                                                                                                                                                              2.10.2运行配置文件中指定类的指定方法

                                                                                                                                                                                                                              • 案例需求
                                                                                                                                                                                                                                • 通过反射运行配置文件中指定类的指定方法
                                                                                                                                                                                                                              • 代码实现

                                                                                                                                                                                                                                3.模块化

                                                                                                                                                                                                                                3.1模块化概述【理解】

                                                                                                                                                                                                                                Java语言随着这些年的发展已经成为了一门影响深远的编程语言,无数平台,系统都采用Java语言编写。但是,伴随着发展,Java也越来越庞大,逐渐发展成为一门“臃肿” 的语言。而且,无论是运行一个大型的软件系统,还是运行一个小的程序,即使程序只需要使用Java的部分核心功能, JVM也要加载整个JRE环境。 为了给Java“瘦身”,让Java实现轻量化,Java 9正式的推出了模块化系统。Java被拆分为N多个模块,并允许Java程序可以根据需要选择加载程序必须的Java模块,这样就可以让Java以轻量化的方式来运行
                                                                                                                                                                                                                                其实,Java 7的时候已经提出了模块化的概念,但由于其过于复杂,Java 7,Java 8都一直未能真正推出,直到Java 9才真正成熟起来。对于Java语言来说,模块化系统是一次真正的自我革新,这种革新使得“古老而庞大”的Java语言重新焕发年轻的活力

                                                                                                                                                                                                                                3.2模块的基本使用【应用】

                                                                                                                                                                                                                                1. 在项目中创建两个模块。一个是myOne,一个是myTwo
                                                                                                                                                                                                                                1. 在myOne模块中创建以下包和以下类,并在类中添加方法
                                                                                                                                                                                                                                  1. notion image
                                                                                                                                                                                                                                    notion image
                                                                                                                                                                                                                                1. 在myTwo模块中创建以下包和以下类,并在类中创建对象并使用
                                                                                                                                                                                                                                  1. notion image
                                                                                                                                                                                                                                    notion image
                                                                                                                                                                                                                                1. 在myOne模块中src目录下,创建module-info.java,并写入以下内容
                                                                                                                                                                                                                                  1. notion image
                                                                                                                                                                                                                                1. 在myTwo模块中src目录下,创建module-info.java,并写入以下内容
                                                                                                                                                                                                                                  1. notion image

                                                                                                                                                                                                                                3.3模块服务的基本使用【应用】

                                                                                                                                                                                                                                1. 在myOne模块中新建一个包,提供一个接口和两个实现类
                                                                                                                                                                                                                                  1. notion image
                                                                                                                                                                                                                                    notion image
                                                                                                                                                                                                                                    notion image
                                                                                                                                                                                                                                1. 在myOne模块中修改module-info.java文件,添加以下内容
                                                                                                                                                                                                                                  1. notion image
                                                                                                                                                                                                                                1. 在myTwo模块中新建一个测试类
                                                                                                                                                                                                                                  1. notion image
                                                                                                                                                                                                                                    notion image
                                                                                                                                                                                                                                1. 在myTwo模块中修改module-info.java文件,添加以下内容
                                                                                                                                                                                                                                  1. notion image