如何优雅的将文件转换为字符串(环绕执行模式&行为参数化&函数式接口|Lambda表达式)
程序员文章站
2022-06-22 08:14:22
首先我们讲几个概念: 环绕执行模式: 简单的讲,就是对于OI,JDBC等类似资源,在用完之后需要关闭的,资源处理时常见的一个模式是打开一个资源,做一些处理,然后关闭资源,这个设置和清理阶段类似,并且会围绕着执行处理的业务逻辑。这就是环绕执行模式。 行为参数化: 函数式编程的一种思想,通过把代码包装为 ......
首先我们讲几个概念:
- 环绕执行模式:
- 简单的讲,就是对于oi,jdbc等类似资源,在用完之后需要关闭的,资源处理时常见的一个模式是打开一个资源,做一些处理,然后关闭资源,这个设置和清理阶段类似,并且会围绕着执行处理的业务逻辑。这就是环绕执行模式。
-
行为参数化:
- 函数式编程的一种思想,通过把代码包装为参数传递行为,即把代码逻辑包装为一个参数,传到方法里。
-
lambda表达式:
- lambda表达式理解为简洁的表示可传递的匿名函数的一种方式,它没有名称,但它有函数体,参数列表,返回类型。可以抛出一个异常类型。包装代码逻辑为参数即使用lambda表达式。
- 函数式接口:
- 本质上是只有一个抽象方法的普通接口,可以被隐式的转换为lambda表达式,需要用注解定义(@functionalinterface)。默认方法和静态方法可以不属于抽象方法,可以在函数式接口中定义。
- 如果函数式接口中额外定义多个抽象方法,那么这些抽象方法签名必须和object的public方法一样,接口最终有确定的类实现, 而类的最终父类是object。 因此函数式接口可以定义object的public方法。
- 关于更多的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); }
为了美观,我把异常抛了出去,这样好处:
- 我们只需要关心具体的读取逻辑即可,不需要关心其他,
- 可以用于文本处理,对读取的字符串进行过滤等操作。
不足之处希望小伙伴批评指教。生活加油..
上一篇: 详解Navicat简单使用方法