今天是我自学Java的第39天。

感谢你的观看,谢谢你。

话不多说,开始今天的学习:

用过安卓手机的同学应该都知道:

打开文件管理,可以查看到文件分类:

所有图片都在图片栏里;所有视频都在视频栏里;所有音乐都在音乐栏里……等等。

那这种需求在Java代码里面要如何做到?

就需要使用到过滤器了。

一、过滤器

什么叫过滤器?

就是根据特定的要求,找出对应条件的文件。

比如说,过滤出图片文件:

java 过滤int类型不为null java过滤器指定过滤文件_java 过滤int类型不为null

①创建一个file对象

路径填写我们现在作为例子的文件夹“F:/test"。

②定义一个find方法

该方法的作用为:查找文件夹中的图片文件。

③file如果是文件

根据后缀名是否为“jpg”来判断图片文件,并输出该文件。

④file如果是文件夹

因为我们要查询的是图片文件,那么要先遍历。

使用file的listFilts方法,再使用增强for循环遍历。

子文件里面可能同时又有文件夹和文件,故递归

⑤递归调用自己

find方法本身就是查找文件夹里的图片文件的,那么直接调用自己就好了。

OK,代码写完,运行下来发现控制台打印的都是文件夹中的图片文件,需求解决。

但是现在问题来了,这种代码写下来水平就很差,因为代码的可拓展性太差了。

什么叫可拓展性?

拓展性越强,需求改变时,需要修改的代码越少。

就拿上述例子来说:是,确实解决了查找图片的需求,但是如果现在要查找音乐文件呢?该怎么办?如果要查找视频文件呢?

得将代码复制粘贴,然后将“jpg”一个个修改,这样的话代码就太冗余了。

如何解决扩展性问题?

二、过滤器优化

java 过滤int类型不为null java过滤器指定过滤文件_java 过滤int类型不为null_02

①定义一个查找方法

设置两个参数:文件对象,后缀名;根据后缀名查找对应的文件。

②如果是文件

根据isFile()方法,判断是否是文件,若是文件再进行判断,同时结束递归。

③判断文件是否满足要求。

根据提供的后缀名,来判断是否满足的要求。

④如果是文件夹

先遍历,再递归。

OK,需求解决了,现在想查找某种类型的文件,直接在调用方法时设定参数就好了。

那么问题又来了:

如果有用户要查询前缀名为a的图片,该怎么办?

如果有用户要查询包含“cad”的图片,又该怎么办?

如果有用户要查询大小小于1M的图片,又该怎么办?

因为用户的需求是各种各样的,程序员得去满足这些要求。

我觉得写代码有一个最大的魅力:实现需求时要考虑的非常全面,这样在遇到问题的时候,能很好地去应对。

就像网上流传的一句话:只有将用户想象成最傻最傻的人,考虑到各种各样的问题,才能写出好的代码。

三、过滤器再次优化

如何进一步优化?仔细看第二节中的代码:

java 过滤int类型不为null java过滤器指定过滤文件_递归_03

③是问题的核心所在,因为③将代码给写死了,endsWith方法只能用来判断后缀名。

那怎么解决这个问题?

接口,Java的精髓就在于接口。

具体什么意思?

现在要查找对应的文件对吧,我不写具体的查找条件了,我就制定一个接口,谁要用接口,重写方法就好了:

要根据后缀名查找文件?行,重写方法就好了。

要根据前缀名查找文件?行,重写方法就好了。

用户有任何要求,只需要重写接口里的方法,写出对应的需求就好了。

高级程序员和低级程序员差别在哪?

高级程序员写出的代码,能解决某类问题,他在写接口,在制定规则。

低级程序员写出的代码,只能解决某个问题,他在实现接口,写出用户具体的要求。

所以接口是每一个Java程序员应该认真研究的:如何使用接口,如何写接口。

回到过滤器,如何写接口?

java 过滤int类型不为null java过滤器指定过滤文件_java 过滤int类型不为null_04

①定义过滤器接口MyFilter

要过滤文件?实现这个接口就好了。

接口里定义一个抽象方法,我给你一个file,具体是什么过滤条件我不清楚,你重写我的方法时写清楚,并将结果告诉我就好了。

②定义一个查找方法find,设定两个参数

一个是file,一个是定义的接口。

为何要拿接口作为参数?因为接口能制定规则。

接口是没法实例化创建对象的,那么无论是谁,你想要使用find方法,必须实现这个接口和重写接口里的抽象方法。

③重写接口里的抽象方法

根据用户的需求,写出具体的过滤条件就好了,再返回一个结果。

④多态

父类引用在调用方法时,会调用子类重写后的方法,这是多态。

这里并没有将过滤条件写死,而是不同的人在调用find方法时,根据不同的重写方法,有不同的结果。

⑤遍历并递归

递归已经说了很多遍了,不再阐述。

所以什么叫代码的可拓展性?

无论用户有什么过滤要求,我只需要修改③中重写的方法就可以了,其他代码都不用改,这就是代码的可拓展性。

还能优化么?是可以的,在③中可以使用lambad表达式代替匿名内部类。

java 过滤int类型不为null java过滤器指定过滤文件_后缀名_05

以上就是关于过滤器一点一点的优化,当然我这写的比较粗糙,我估计都存在什么问题,只不过我自己水平有限,没有发现而已。

但核心思想还是考虑到了的。

核心思想是啥?

就是接口、面向对象三大特性之一的多态。

当一个方法里参数有接口时,必定会有多态,因为接口没法实例化创建对象,必定需要其实现类对象。