作者 | Java圣斗士 | 原创图文,转载请注明出处
全文约2000字,阅读需10分钟
哈喽大家好,我是又皮又可爱的Java圣斗士,关注我,每天带你飞!
看到标题,相信很多小伙伴都已经猜到今天的代码课题是在指定文件中查找指定字符串的出现频率。
其实作为一种通用的功能型需求,有人说:不要重复造轮子,有现成的API,直接调用就好了!可是圣斗士要说了,不要重复造轮子的前提是你会造轮子,为了能够更好的学会造轮子,我依然会学习大量的源码和底层技术书籍。其实,有心的小伙伴在面试的时候都已经能够体会到IT大厂的面试题之深度和精度,什么Hash、数据结构、算法、Spring实现原理等等,我们的确是在一直用着这些“轮子”,但如果不真正理解他们,具备能够“造轮子”的能力,那技术之路会很快走到尽头的!
好了,废话不多说,我们进入今天的代码实现环节。
一、如何统计字符串出现次数
做过文件系统的小伙伴可能对文件处理深有体会,经常会需要进行某种类型的搜索。那么如何在一个文件中查找某个指定字符串的出现次数呢?先来看看代码实现:
public static int countWordInFile(String filename, String word) {int counter = 0;try (FileReader fr = new FileReader(filename)) {try (BufferedReader br = new BufferedReader(fr)) {String line = null;while ((line = br.readLine()) != null) {int index = -1;while (line.length() >= word.length()&& (index = line.indexOf(word)) >= 0) {counter++;line = line.substring(index + word.length());}}}} catch (Exception ex) {ex.printStackTrace();}return counter;}
然后我们通过一个main方法,来测试一下这个“轮子”:
public static void main(String[] args) {String path = "D:estmyFile.txt";int num = CountUtil.countWordInFile(path, "Hello World");System.out.println("字符串出现次数:" + num + " 次");}
执行结果:
动图中间的部分是为了更好的比较而展示的文件本身的字符串查找结果,可以看到,文件中”Hello World”的出现次数是3次,程序的执行结果也是3次,完全正确。
那么我们就来解析一下这段代码。
二、代码精解
首先在countWordInFile()方法中,我们指定一个文件路径和一个需要被查找的关键字 word:
countWordInFile(String filename, String word) {
然后紧接着创建FileReader和BufferedReader,这里的API用到了装饰器模式,这种设计模式允许向一个现有的对象添加新的功能,同时又不改变其结构,往往会用于增强原有对象的功能。
紧接着,我们的程序会通过readLine()方法读取文件中每行字符串:
while ((line = br.readLine()) != null) {
readLine()方法就是BufferedReader对象相对于FileReader新增的方法,这个方法会读取文件中的一行字符串,任何以 “”或者回车结尾的都被视为一行字符串,如果返回值是null那么代表“the end of the stream has been reached”流已经到头了,即没有任何内容了。
然后是对前面读出的每一行进行字符串的规则匹配:
while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {counter++;line = line.substring(index + word.length());}
这个while是行内循环,首先要判断line的长度是否大于等于word的长度,如果想要包含word字符串,那么就必须在长度上要大于word,然后indexOf()方法会返回一个字符下标,它会判断word是否在该字符串中,如果不在,那么就会返回 -1,如果在,那么就会返回该word的第一个字母在line中的字符下标。
然后在while的方法体中,修改计数器,并且通过substring来继续向后面的字符串进行同样逻辑的查找,直到line的长度小于word的长度为止。
总结
我们通常判断一个字符串是否在另一个字符串中会使用string.indexOf()方法,这个方法也是匹配规则的关键,那么需求从字符串中查找word变成了在文件中查找word,就需要增加额外的逻辑。
我们的思路就是while循环读取文件中的每行文字,使用到的函数是bufferedReader.readLine(),这个方法会返回整行字符串,如果读到头了,那么就会返回null。
拿到了readLine()的整行字符串,我们就可以套用字符串中查找关键字的流程使用indexOf()来完成逻辑。
其实总体思路还是很清晰的,你学会了吗?!
往期精彩:
《对话式情景剖析,String被final修饰的真正原因!一篇足矣》
《必考!Java参数传递的真正秘密》
《5分钟带你快速了解建造者模式》
《为了降低抽象工厂模式的复杂度,我决定这样做》
《能否成为架构师?抽象工厂模式,真正考验你抽象能力的时候到了》
---欢迎关注【Java圣斗士】,我是你们的小可爱(✪ω✪) Morty---
---专注IT职场经验、IT技术分享的灵魂写手---
---每天带你领略IT的魅力---
---期待与您陪伴!---