首先我们讲几个概念:
环绕执行模式:
简单的讲, 就是对于 OI,JDBC 等类似资源, 在用完之后需要关闭的, 资源处理时常见的一个模式是打开一个资源, 做一些处理, 然后关闭资源, 这个设置和清理阶段类似, 并且会围绕着执行处理的业务逻辑. 这就是环绕执行模式.
行为参数化:
函数式编程的一种思想, 通过把代码包装为参数传递行为, 即把代码逻辑包装为一个参数, 传到方法里.
Lambda 表达式:
Lambda 表达式理解为简洁的表示可传递的匿名函数的一种方式, 它没有名称, 但它有函数体, 参数列表, 返回类型. 可以抛出一个异常类型. 包装代码逻辑为参数即使用 Lambda 表达式.
函数式接口:
本质上是只有一个抽象方法的普通接口, 可以被隐式的转换为 Lambda 表达式, 需要用注解定义 (@FunctionalInterface). 默认方法和静态方法可以不属于抽象方法, 可以在函数式接口中定义.
如果函数式接口中额外定义多个抽象方法, 那么这些抽象方法签名必须和 Object 的 public 方法一样, 接口最终有确定的类实现, 而类的最终父类是 Object. 因此函数式接口可以定义 Object 的 public 方法.
关于更多的 java8 学习,《Java8实战》个人感觉这本书不错. 也可以看看我的博客,《java8 实战》读书笔记, 里面有这本书的PDF资源
- @FunctionalInterfacepublic
- interface ObjectMethodFunctionalInterface {
- void count(int i);
- String toString(); //same to Object.toString
- int hashCode(); //same to Object.hashCode
- boolean equals(Object obj); //same to Object.equals
- }
下面我们先看一个简单的环绕执行模式:
第一步; 当需要更改逻辑代码是, 需要重写代码, 所以想到行为参数化
- public static String processFile()throws IOException {
- try(BufferedReader bufferedReader =
- new BufferedReader(new FileReader("data.txt"))){
- // return bufferedReader.readLine();
- return bufferedReader.readLine()+bufferedReader.readLine();
- }
第二步, 使用函数式接口来传递一个行为
- @FunctionalInterface
- public interface BufferReaderProcessFile{
- // 方法签名为 BufferReader -> String
- String peocess(BufferedReader bufferedReader)throws IOException;
- }
第三步, 执一个行为, 任何 BufferReader -> String 的 Lambda 表达式都可以作为参数传入. 只要符合 peocess 方法的签名即可.
- public static String processFiles(BufferReaderProcessFile bufferReaderProcessFile)throws IOException {
- try(BufferedReader bufferedReader =
- new BufferedReader(new FileReader("data.txt"))){
- return bufferReaderProcessFile.peocess(bufferedReader) ;
第四步, 传递 Lambda
String string = processFiles((BufferedReader bs) ->bs.readLine());
文件转换为字符串, 我的思路, 我对 java IO 用的不是很熟, 大家有好的方法请留言, 相互学习:
- FileInputStream fileInputStream = new FileInputStream(file))
- InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream))
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader))
- String str = bufferedReader.readLine()
字节流 -》字符流 -》字符缓存流 即 将字节流转换为字符流之后在用高级流包装.
所以我的思路是避免在逻辑里出现太多的 IO 流关闭, 和异常捕获, 专心处理读取逻辑即可, 结合以下两种技术:
try(){}[自动关闭流, 1.7 支持]
lambda 特性来实现 [行为参数化, 1.8]
步骤:
函数式接口传递行为的定义:
- package com.liruilong.demotext.service.utils.interfaceutils;
- import java.io.BufferedReader;
- import java.io.IOException;
- /**
- * @Description : 函数接口, 描述 BufferedReader ->String 的转化方式
- * @Author: Liruilong
- * @Date: 2020/3/17 15:44
- */
- @FunctionalInterface
- public interface InputStreamPeocess {
- /**
- * @Author Liruilong
- * @Description 方法签名 BufferedReader ->String
- * @Date 15:47 2020/3/17
- * @Param [inputStream]
- * @return com.liruilong.demotext.service.utils.InputStream
- **/
- String peocess(BufferedReader bufferedReader) throws IOException;
- }
执一个行为, 任何 BufferReader -> String 的 Lambda 表达式都可以作为参数传入. 只要符合 peocess 方法的签名即可.
- /**
- * @return java.lang.String
- * @Author Liruilong
- * @Description 环绕处理
- * @Date 17:14 2020/3/17
- * @Param [inputStreamPeocess, file]
- **/
- public static String fileToBufferedReader(InputStreamPeocess inputStreamPeocess, File file) throws IOException {
- try (FileInputStream fileInputStream = new FileInputStream(file)) {
- try (InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream)) {
- try (BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
- return inputStreamPeocess.peocess(bufferedReader);
- }
- }
- }
- }
执行 Lambda
- /**
- * @return java.lang.String
- * @Author Liruilong
- * @Description 文件转字符串
- * @Date 17:22 2020/3/17
- * @Param [file]
- **/
- public static String readJsonToString(File file)throws IOException {
- return string = fileToBufferedReader((bufferedReader) -> {
- String str = null;
- StringBuilder stringBuilder = new StringBuilder();
- while ((str = bufferedReader.readLine()) != null) {
- stringBuilder.append(str);
- }
- return stringBuilder.toString();
- }, file);
- }
为了美观, 我把异常抛了出去, 这样好处:
我们只需要关心具体的读取逻辑即可, 不需要关心其他,
可以用于文本处理, 对读取的字符串进行过滤等操作.
不足之处希望小伙伴批评指教. 生活加油..
来源: https://www.cnblogs.com/liruilong/p/12678103.html