博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
行为参数化
阅读量:4538 次
发布时间:2019-06-08

本文共 5651 字,大约阅读时间需要 18 分钟。

行为参数话的理解:

  行为参数化有些类似策略模式,但是更精简。表面来看就是定义一个函数式接口(只定义一个抽象方法的接口),实现这个接口然后把实现类的实例当做参数加入到方法中。行为参数化可以很好的应对不断变更的需求,使代码更优雅。

下面看看示例(来自《Java8实战》)

  模拟场景:我们有个客户是水果大王,他想要一个系统来帮助他快速的把收来的苹果进行分类然后分销的不同的地区。第一次跟他谈需求,他说他想要把重量大于5kg的苹果发往西北,把重量小于5kg的苹果发往华东。我们根据他的需求开始开发,

做到中途,水果大王突然联系我们说需要改需求,他还想根据颜色来把苹果分来然后发往不同的区域。我们眉头一皱,还好我们可以用行为参数化的方法来改需求。否则又是浩大的工作量啊!

  步骤一:定义一个苹果类

package org.burning.sport.javase.lambda;public class Apple {    private int weight;    private String color;    public Apple(int weight, String color) {        this.weight = weight;        this.color = color;    }   setters();getters();toString();}

  步骤二:定义一个函数式接口,这个接口里的抽象方法就是用来规定怎么区分苹果的,返回一个boolean值

package org.burning.sport.javase.lambda;/** * 函数式接口 */public interface ApplePredicate {    boolean test(Apple apple);}

  步骤三:定义两个实现类,分别是区分颜色的和区分重量的

package org.burning.sport.javase.lambda;public class AppleColorPredicate implements ApplePredicate {    /** 筛选出红色的苹果 */    @Override    public boolean test(Apple apple) {        return "red".equals(apple.getColor());    }}
package org.burning.sport.javase.lambda;public class AppleWeightPredicate implements ApplePredicate{    /** 筛选出重量大于5kg的苹果 */    @Override    public boolean test(Apple apple) {        return apple.getWeight() > 5;    }}

   步骤四:使用行为参数

package org.burning.sport.javase.lambda;import java.util.ArrayList;import java.util.List;/** * 行为参数化示例 */public class LambdaTest1 {    public static List
filterApples(List
apples, ApplePredicate predicate) { List
result =new ArrayList<>(); for(Apple apple : apples) { if(predicate.test(apple)) { result.add(apple); } } return result; } public static void main(String[] args) { List
appleList = new ArrayList<>(); appleList.add(new Apple(10, "green")); appleList.add(new Apple(5, "red")); appleList.add(new Apple(5, "green")); appleList.add(new Apple(10, "red")); //找出颜色是红色的苹果 List
resultColor = filterApples(appleList, new AppleColorPredicate()); System.out.println(resultColor.toString()); //找出重量大于5的苹果 List
resultWeight = filterApples(appleList, new AppleWeightPredicate()); System.out.println(resultWeight.toString()); }}

  看了上面的例子,我们发现还不是很灵活,如果水果大王又开始卖橙子卖香蕉了呢?所以我们再做一下改造,用到了泛型,将行为参数泛型化。

  步骤一:定义一个泛型化的函数接口

package org.burning.sport.javase.lambda;public interface Predicate
{ boolean test(T t);}

  步骤二:定义一个橙子实体类

package org.burning.sport.javase.lambda;public class Orange {    private int weight;    private String color;    public Orange(int weight, String color) {        this.weight = weight;        this.color = color;    }    setters();getters();toString();}

  步骤三:定义两个实现类,分别是区分橙子的颜色和重量

package org.burning.sport.javase.lambda;public class ColorPredicate implements Predicate
{ @Override public boolean test(Orange orange) { //筛选出橙色的橙子 return "orange".equals(orange.getColor()); }}
package org.burning.sport.javase.lambda;public class WeightPredicate implements Predicate
{ @Override public boolean test(Orange orange) { //筛选出大于5kg的橙子 return orange.getWeight() > 5; }}

  步骤四:使用新定义的泛型化行为参数

package org.burning.sport.javase.lambda;import com.google.common.collect.Lists;import java.util.ArrayList;import java.util.List;public class LambadTest2 {    public static 
List
filter(List
fruits, Predicate
predicate) { List
results= new ArrayList<>(); for(T t : fruits) { if(predicate.test(t)) { results.add(t); } } return results; } public static void main(String[] args) { ArrayList
oranges = Lists.newArrayList( new Orange(10, "green"), new Orange(4, "green"), new Orange(4, "orange"), new Orange(10, "green")); List
resultColorList = filter(oranges, new ColorPredicate()); System.out.println(resultColorList.toString()); System.out.println("================="); List
resultWeightList = filter(oranges, new WeightPredicate()); System.out.println(resultWeightList.toString()); }}

   上面的例子有很好的扩展性,还可以。但是还是得多写两个“套路”的实现类,有没有更简洁一点的“套路”呢?有,用Lambda表达式

package org.burning.sport.javase.lambda;import com.google.common.collect.Lists;import java.util.ArrayList;import java.util.List;public class LambdaTest3 {    public static 
List
filter(List
fruits, Predicate
predicate) { List
results= new ArrayList<>(); for(T t : fruits) { if(predicate.test(t)) { results.add(t); } } return results; } public static void main(String[] args) { ArrayList
oranges = Lists.newArrayList( new Orange(10, "green"), new Orange(4, "green"), new Orange(4, "orange"), new Orange(10, "green")); ArrayList
apples = Lists.newArrayList( new Apple(10, "red"), new Apple(10, "green"), new Apple(3, "red"), new Apple(3, "green")); // Lambda表达式 List
orangeWeightList = filter(oranges, o -> o.getWeight() > 5); List
appleWeightList = filter(apples, a -> a.getWeight() > 5); System.out.println(orangeWeightList); System.out.println("==============="); System.out.println(appleWeightList); }}

   最后再补充几个概念吧:

   1、任何函数式接口都不允许抛出受检查异常(check exception)

   2、Lambda仅可用于上下文是函数式接口的情况

  好啦,就这样吧,现学现卖结束啦。

 

参考:

【1】《Java8实战》

 

转载于:https://www.cnblogs.com/happyflyingpig/p/9042963.html

你可能感兴趣的文章
C#winform自定义控件模拟设计时界面鼠标移动和调节大小、选中效果
查看>>
DIV非偏移放大
查看>>
Jquery 展开收起
查看>>
css的选择器优先级
查看>>
C#快捷键
查看>>
linux下安装mysql
查看>>
selenium+Python(处理html5的视频播放)
查看>>
在Winform开发中使用FastReport创建报表
查看>>
C# 反射研究
查看>>
[原创][Verilog]个人.v文件书写规范
查看>>
[原创]Matlab获取当前时间信息
查看>>
Bulma 中的媒体查询
查看>>
手机新闻网页
查看>>
【Android Studio安装部署系列】一、JDK开发环境搭建
查看>>
window平板的几个快捷操作
查看>>
[LeetCode 题解]: Binary Tree Preorder Traversal
查看>>
WebAPI使用多个xml文件生成帮助文档
查看>>
Android开发:APK的反编译(获取代码和资源文件)
查看>>
Online Judge(OJ)搭建——2、数据库,SQL语句
查看>>
描述网络的优点与缺点
查看>>