java se 进阶_08-08总结(JavaSE进阶 下)

1、Lambda表达式

1.函数式编程思想概述

在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿什么东西做什么事情”。相对而言,面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做。

我们真的希望创建一个匿名内部类对象吗?不。我们只是为了做这件事情而不得不创建一个对象。

传递一段代码才是我们真正的目的。而创建对象只是受限于面向对象语法而不得不采取的一种手段方式。那,有没有更加简单的办法?如果我们将关注点从“怎么做”回归到“做什么”的本质上,就会发现只要能够更好地达到目的,过程与形式其实并不重要。

2.Lambda表达式

格式

Lambda省去面向对象的条条框框,格式由3个部分组成:

一些参数()

一个箭头  ->

一段代码  { }

Lambda表达式中小括号中的内容就是: 重写方法的参数列表

Lambda表达式中大括号中的内容就是: 重写方法的方法体

f2fc48c4f4a1

3.Lambda表达式使用的前提

必须存在一个函数式接口;函数式接口必须作为方法的参数(最为常用)/方法的返回/给变量赋值

函数式接口 : 有且只有一个抽象方法的接口。函数式接口有特殊的注解: @FunctionalInterface

4.Lambda的简化(省略)格式

可推导可省略

省略规则

小括号中数据类型可以省略

小括号中如果只有一个参数, 小括号可以省略

大括号中如果只有一条语句, 大括号和分号可以省略(不能省略一部分)

大括号中如果只有一条语句, 且还是返回语句, 大括号和分号以及return可以省略

2、Stream流

1.引入

每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环是做事情的方式,而不是目的。另一方面,使用线性循环就意味着只能遍历一次。如果希望再次遍历,只能再使用另一个循环从头开始。

那,Lambda的衍生物Stream能给我们带来怎样更加优雅的写法呢?

f2fc48c4f4a1

这段代码可以优雅地改为如下写法

f2fc48c4f4a1

直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印。代码中并没有体现使用线性循环或是其他任何算法进行遍历,我们真正要做的事情内容被更好地体现在代码中。

备注:“Stream流”其实是一个集合元素的函数模型,它并不是集合,也不是数据结构,其本身并不存储任何元素(或其地址值)。

2. 获取流的方式

List, Set, Map -> xxx.stream()

引用数据类型数组, 一堆数据 -> Stream.of(xxx)

// List

List list = new ArrayList<>();

Stream stream1 = list.stream();

// Set

Set set = new HashSet<>();

Stream stream2 = set.stream();

// Map

Map map = new HashMap<>();

// 所有键

Stream stream3 = map.keySet().stream();

// 所有值

Stream stream4 = map.values().stream();

// 所有键值对

Stream> stream5 = map.entrySet().stream();

// 引用数据类型的数组

Integer[ ] arr2 = {1, 2, 3};

Stream stream7 = Stream.of(arr2);

// 基本数据类型数组

int[ ] arr = {1, 2, 3};

Stream stream6 = Stream.of(arr); // 把整个数组, 当成流中的一个元素

// 一堆数据(同一种数据类型)

Stream stream8 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);

3. Stream流中的方法

函数拼接与终结方法

在下面几种方法中,凡是返回值仍然为Stream接口的为函数拼接方法,它们支持链式调用;而返回值不再为Stream接口的为终结方法,不再支持链式调用。

方法名                    方法作用                    方法种类                是否支持链式调用

count                      统计个数                    终结                        否

forEach                   逐一处理                    终结                        否

filter                        过滤函数                     拼接                        是

limit                        取用前几个函数           拼接                        是

skip                        跳过前几个函数           拼接                        是

map                       映射函数                      拼接                         是

concat                   组合函数                      拼接                          是

注意事项:

不可以操作已经操作过的流

如果流已经关闭了, 不可以继续使用

3、File

1.构造方法

public File(String pathname)                        创建一个File对象, 路径为参数指定的pathname

public File(String parent, String child)          创建一个File对象, 路径是参数中两个字符串拼接起来(parent + child)

public File(File parent, String child)              创建一个File对象, 路径是父级parent对应的路径字符串, 和子级字符

串拼接起来

2.其他方法

public long length()                                        获取文件的大小(字节的个数), 不能获取文件夹

public String getAbsolutePath()                     获取绝对路径

public String getPath()                                   获取构造方法中的路径

public String getName()                                 获取文件或者文件夹的名称(最后一个)

3.判断功能

public boolean exists()                                    判断文件或者文件夹是否存在

public boolean isDirectory()                            判断是否是文件夹

public boolean isFile()                                     判断是否是文件

4.创建功能

public boolean createNewFile()                       如果文件不存在, 创建新文件, 创建成功返回true否则返回false

public boolean mkdir()                                     创建单级文件夹(目录)

public boolean mkdirs()                                   创建多级文件夹(目录), 也能创建单级的文件夹

5.删除功能

public boolean delete()                                    删除文件和文件夹(文件夹必须是空的;删除的内容不走回收站)

6.遍历文件夹功能

public String[] list()                                           获取当前文件夹中的所有文件和文件夹, 存储到字符串数组中

public File[] listFiles()                                       获取当前文件夹中所有文件和文件夹(以File形式), 存储到FIle数组中

public File[] listFiles() 方法使用过滤器

File[] subFiles = file.listFiles(p -> p.getName().endsWith(".java") && p.isFile());

4、字节流

输入流输出流

字节流:字节输入流InputStream/字节输出流OutputStream

字符流:字符输入流Reader/字符输出流Writer

1.字节输出流

构造方法

public FileOutputStream(File file)             创建字节输出流, 流关联参数中File指定的文件

public FileOutputStream(String name)     创建字节输出流, 流关联参数中String路径指定的文件

输出流关联的文件, 如果不存在, 会自动创建

非追加场景中, 输出流关联的文件如果存在, 会清空

写出方法

public void write(int b)                                   写出一个字节, 将参数中的int转换成byte

public void write(byte[] b)                              写出字节数组

public void write(byte[] b, int off, int len)        写出b数中的的字节, 从off索引开始的len个

写出换行

fos.write("\r\n".getBytes());        //“\r\n”表示换行符,getBytes方法把字符串转换成字节数组,write写出字符数组

追加写出

public FileOutputStream(String name, boolean append)        append为true, 追加写出

public FileOutputStream(File file, boolean append)                append为true,追加写出

2.字节输入流

构造方法

public FileInputStream(File file)                    创建字节输入流对象, 关联的文件是file指定的文件

public FileInputStream(String name)            创建字节输入流对象, 关联的文件是name路径指定的文件

输入流关联的文件如果不存在, 就会报错.

读取方法

public int read()                    从输入流关联的文件中读取一个字节(自动将byte类型转换成int类型),如果读                                                           取到文件的末尾返回-1

public int read(byte[] b)        从输入流关联的文件中读取最多b.length个字节,将字节读取到参数中的字节数                                                          组中,返回值:如果读取到内容, 返回值代表读取到有效的字节个数,如果读取到                                                       文件的末尾, 返回-1

3. 文件的拷贝(一个字节拷贝/字节数组拷贝)

详见随笔/JavaEE经典案例

5、字符流

字符流的读取: 将字节转换成字符读取到内存中

字符流的写出: 将字符转换成字节写出到硬盘中

所以, 在不是我们能看得懂的纯文本文件中, 使用字符流一定会出现问题.

构造方法

FileWriter(File file):                 创建一个新的 FileWriter,给定要读取的File对象。

FileWriter(String fileName):     创建一个新的 FileWriter,给定要读取的文件的名称。

成员方法

public void write(int c) :写出一个字符。

public void write(char[] cbuf):将 b.length字符从指定的字符数组写出此输出流。

public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量 off开始输出到                                                                                           此输出流。

public void write(String str) :写出一个字符串

什么时候用字节流, 什么时候用字符流?

所有格式文件的拷贝, 都可以使用字节流

我们能看得懂的纯文本文件, 也可以使用字符流拷贝(其他所有格式都不能使用字符流)。字符流拷贝的过程中, 有字节到字符和字符到字节的转换。

关闭和刷新

Writer这个流中, 内部自带缓冲区(数组), 写出的数据会先写到缓冲区中.

缓冲区中的内容, 写出(刷新/刷出)到有两个条件:

1.手动刷出(close() / flush())

2.缓冲区满了, 自动刷

close() : 关流, 在关流之前, 会刷出一次缓冲区.

flush() : 会刷出一次缓冲区

6、属性集

1.概述

java.util.Properties 继承于Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时,System.getProperties 方法就是返回一个Properties对象。

2.Properties作为Map的使用

// Properties : 没有泛型, 因为Properties中已经默认键和值的数据类型都是String

public Object setProperty(String key, String value) : 相当于put方法, 想集合中存储键值对

public String getProperty(String key) : 相当于get方法, 根据键获取值

3. Properties作为配置文件的使用

public void load(InputStream inStream) : 从输入流关联的文件中, 读取到配置信息, 将配置信息存储到                                                                                      Properties集合中

public void store(OutputStream out, String comments) :  将内存Properties中的信息, 保存到输出流关联的配                                                                                                    置文件中;comments: 注释, 说明

7、缓冲流

1.概述

缓冲流,也叫高效流,是对4个基本的FileXxx 流的增强,所以也是4个流,按照数据类型分类:

字节缓冲流:BufferedInputStream,BufferedOutputStream

字符缓冲流:BufferedReader,BufferedWriter

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

2.构造方法

public BufferedInputStream(InputStream in)

public BufferedOutputStream(OutputStream out)

3.带缓冲区的字符输入流BufferedReader

构造方法

public BufferedReader(Readerin)

读取一行

public StringreadLine() :读取一行,遇到换行符("\r\n")代表一行结束

返回:读取到的一行,不包含换行符,如果到末尾返回null

4.带缓冲区的字符输出流: BufferedWriter

构造方法

public BufferedWriter(Writerout)

写入换行

public void newLine() :写出一个换行符(跨平台)

8、转换流

InputStreamReader : 是字节流通向字符流的桥梁, 可以使用指定字符集将字节转换成字符.

OutputStreamWriter : 是字符流通向字节流的桥梁, 可以使用指定的字符集将字符转换成字节

构造方法

public InputStreamReader(InputStream in,/ / 字节输入流 String charsetName // 字符集的名称)

public OutputStreamWriter(OutputStream out, // 字节输出流 String charsetName) // 字符集的名称

9、序列化流

1.概述

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象。

2.序列化操作

一个对象要想序列化,必须满足两个条件:

该类必须实现java.io.Serializable 接口,Serializable 是一个标记接口,不实现此接口的类将不会使任何状态     序列化或反序列化,会抛出NotSerializableException 。

该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用     transient 关键字修饰

3. 输入流ObjectInputStream

构造方法

public ObjectInputStream(InputStream in)

成员方法

public final Object readObject() : 读取对象

10、装饰设计模式

装饰模式指的是在不改变原类, 不使用继承的基础上,动态地扩展一个对象的功能。上面介绍的几个增强流就是在字节流的基础上扩展了一些特殊的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值