Java8实战——通过行为参数化传递代码
1、初试牛刀:筛选绿苹果
第一个解决方案可能是下面这样的:
public static List<Apple> filterGreenApples(List<Apple> inventory){ List<Apple> result=new ArrayList<>(); //仅仅筛选出绿苹果 for (Apple apple : inventory) { if ("green".equals(apple.getColor())){ result.add(apple); } } return result; }
上面代码只针对绿苹果进行筛选,现在,我还想筛选出红苹果,该怎么做呢?简单的解决办法就是重复写一个方法,再改条件为红苹果,但是,要筛选的颜色有多种的情况,这样写会导致代码十分冗余,所以我们第一步尝试将其抽象化。
2、再展身手:把颜色作为参数
public static List<Apple> filterGreenApples(List<Apple> inventory,String color){ List<Apple> result=new ArrayList<>(); //颜色作为参数 for (Apple apple : inventory) { if (color.equals(apple.getColor())){ result.add(apple); } } return result; }
但是现在又想根据苹果的重量对苹果进行筛选,那是不是也要用另外一个参数表示苹果重量呢?之后我又想加个标志区分对颜色和重量的查询呢?下面是展示一般写法,但是很傻。
3、第三次尝试:对你能想到的每个属性做筛选
public static List<Apple> filterGreenApples(List<Apple> inventory,String color,int weight,boolean flag){ List<Apple> result=new ArrayList<>(); for (Apple apple : inventory) { if (flag && color.equals(apple.getColor())|| (!flag && apple.getWeight()>weight)){ result.add(apple); } } return result; }
4、柳暗花明:行为参数化
我们可以把行为进行参数化,来达到更高层次的抽象,首先定义一个统一的标准接口,再通过不同子类对其进行实现,这有点类似于策略设计模式的赶脚。
//封装了对选择苹果的策略 public interface ApplePredicate { //具体算法交给子类去实现 boolean test (Apple apple); }
//颜色算法 public class AppleGreenColorPredicate implements ApplePredicate { @Override public boolean test(Apple apple) { return "green".equals(apple.getColor()); } } //重量算法 public class AppleHeavyWeightPredicate implements ApplePredicate { @Override public boolean test(Apple apple) { return apple.getWeight()>150; } }
5、第四次尝试:根据抽象条件筛选
public static List<Apple> filterApples(List<Apple> inventory,ApplePredicate p){ List<Apple> result = new ArrayList<>(); //行为参数化 for (Apple apple : inventory) { if (p.test(apple)){ result.add(apple); } } return result; }
我们在使用的时候可以传递不同的策略实现来达到目的
List<Apple> heavyApples = filterApples(inventory, new AppleHeavyWeightPredicate()); List<Apple> greenApples = filterApples(inventory, new AppleGreenColorPredicate());
但是这样有个问题,就是每个策略我都要定义一个实现类去实现某个算法,导致后面如果有很多策略,会增加很多的类,我们知道使用匿名类也是一种不错的选择
6、第五次尝试:使用匿名类
List<Apple> redApples = filterApples(inventory, new ApplePredicate() { @Override public boolean test(Apple apple){ return "red".equals(apple.getColor()); } });
但是问题又来了,匿名类还是不够好,第一,它往往很笨重,占用了很多的空间,第二,使用起来让人费解,导致代码可读性不高,即使匿名类处理在某种程度上改善了为一个接口声明好几个实体类的啰嗦问题,但是还是不能令人满意,自java8引入的lambda表达式——一种更简洁的传递代码的方式解决了这个问题。下面我们利用lambda表达式来改写前面的代码吧
7、第六次尝试:使用Lambda表达式
List<Apple>result= filterApples(inventory, (Apple apple)-> "red".equals(apple.getColor()));
不得不承认,使用lambda表达式改写之前的代码确实干净很多,因为它看起来更像问题陈诉本身了,解决了啰嗦的问题
8、第七次尝试:将List类型抽象化
在通往抽象的路上,我们还可以进一步。目前filterApples方法还只适用Apple,我们还可以尝试适用在其他水果上。
public interface Predicate<T> { boolean test(T t); }
//映入类型参数T public static<T> List<T> filter(List<T> list,Predicate<T> p){ List<T> result =new ArrayList<>(); for (T e : list) { if (p.test(e)){ result.add(e); } } return result; }
现在你可以吧filter方法作用在橘子,香蕉等列表上了。
9、小结
行为参数化,就是一个方法接收不同的行为作为参数,并在内部使用他们,完成不同行为的能力。
行为参数化可以让代码更好的适应不断变化的要求,减轻未来的工作量。
传递代码,就是将新行为作为参数传递给方法,但是在java8之前实现起来很啰嗦。为接口声明许多只用一次的实体类而造成的啰嗦代码,在java8之前可以用匿名类来减少。
java API 包含很多可以用不同行为进行参数化的方法,包括排序、线程等。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
不用 PS 抠图,Python + OpenCV 实现自动海报场景替换!
现存在一个问题,就下面图片中的两本书而言,怎样快速让中间边的书本与左边书本对齐(最终效果能实现两张图片重叠(最终结果为右图)),进行的图像转变可旋转、平移、缩放、形变。 本文主要内容就是介绍利用 Opencv 来怎样解决上面的问题,解决这个问题需要三步 确定至少四组对应点坐标 找到一个转换矩阵; 把找到的转换矩阵应用到 Moving Image(需要移动的图片)上,实现图像对齐 图片旋转、平移、缩放等操作的主要目的,就是要最终实现两图像中点对点一一映射关系,图像映射本质上就是像素点转换 图中标记了其中四组对应点,分别标为不同的颜色,分别标为红、橙、黄和绿四种颜色;比如这里的 和 是就是一组对应点,图片经过转换之后 点 必须映射到 点位置。 涉及图片中点坐标变换,都需要借助于 矩阵 运算,这里探究的图像维度都属于二维,坐标只需要 即可 面向此类转换问题,Homography 转换 ( 3 × 3 矩阵) 可用于解决此类转化问题,用来解决点对点映射问题,Homography 矩阵可写作下列方式:则 、 作为对应点,则 Homography 的的应用 如下:而矩阵 H 参数的确定至少需要 ...
- 下一篇
Kube-OVN v1.3,容器网络硬件加速,自定义网关,网关 QoS 以及更多
Kube-OVN 从 1.3 起开始支持基于智能网卡的硬件加速,能够大幅提升容器网络吞吐量,降低网络延迟,并且能减少主机CPU的损耗,可以大幅提升裸金属场景下的性能和资源利用率。 本版本同时增加了网关的功能,用户可以自定义Pod路由策略选择集群内的特定Pod作为流量网关并进行自定义的网关功能开发,例如 EIP,计费,审计等功能。 同时,网关增加了QoS控制的功能,用户可以对同一子网的总对外带宽进行动态调整。 新功能: 容器网络硬件卸载 用户自定义容器网关 集中式网关QoS控制 Session Affinity Service 支持 Round-Robin IP 分配策略 安全: 使用 gosec 审计代码安全 使用 trivy 进行镜像安全审计 升级 CNI 插件修复 CVE 监控: 支持 ovs-tracing 新增外部dns解析指标数据 其他: 升级 OVN 至 20.06 CRD 版本升级至 v1 优化 ARM 构建 优化 ovs-vsctl 调用 优化 OVS-DPDK 镜像
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- 2048小游戏-低调大师作品
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker快速安装Oracle11G,搭建oracle11g学习环境