美文网首页
Java8函数式编程之一: 行为参数化

Java8函数式编程之一: 行为参数化

作者: linkinparkzlz | 来源:发表于2017-10-31 22:26 被阅读370次

    Java8区别于以前的Java版本的一个重要特点就是函数式编程的风格。

    那什么是函数式的编程风格呢?

    理解函数式编程之前让我们先看一下以前的编程方式,也就是命令式编程。比如计算两个数的和:

    public static int add(int a, int b){

    return a + b;

    }

    命令式编程传递的是数据,也就是参数a和参数b;而函数式编程传递的则是行为。比如,“相加”这个操作就是一种行为,或者说是动作。

    函数式编程是将“行为”或者“动作”作为参数,也就是行为参数化。

    在讲解具体的行为参数化之前,我们看看为什么需要行为参数化。

    ——————————————————————————

    这是一个实体域,表示一个公司的所进行的交易。

    importjava.util.Date;

    public classTrade {

    private intid;//交易的id

    privateStringcountry;//交易的国家

    privateDatedate;//交易的日期

    private doublemoney;//交易的金额

    privateStringtrader;//交易员

    public intgetId() {

    returnid;

    }

    public voidsetId(intid) {

    this.id= id;

    }

    publicString getCountry() {

    returncountry;

    }

    public voidsetCountry(String country) {

    this.country= country;

    }

    publicDate getDate() {

    returndate;

    }

    public voidsetDate(Date date) {

    this.date= date;

    }

    public doublegetMoney() {

    returnmoney;

    }

    public voidsetMoney(doublemoney) {

    this.money= money;

    }

    publicString getTrader() {

    returntrader;

    }

    public voidsetTrader(String trader) {

    this.trader= trader;

    }

    }

    ——————————————

    现在有一个需求,你的老板需要筛选出在美国发生的交易

    //筛选出在美国发生的交易

    public staticList filterTradeInAmerica(List trades) {

    List list =newArrayList<>();

    for(Trade trade : trades) {

    if("America".equals(trade.getCountry())) {

    list.add(trade);

    }

    }

    returnlist;

    }

    ——————————————

    如果现在你的老板改变主意了,他需要找出在英国进行的交易怎么办?

    你可能会觉得简单,只需要将方法名字改为filterTradeInUK,然后将if语句里换一下就可以。

    但是这样会造成很多的重复代码,并且国家那么多,你不可能一个一个的每个都写。

    ——————

    当然,大家会想到这样一种方法,将国家作为参数传递。

    //将国家作为参数传递

    public staticList filterTradeByCountry(List trades, String country) {

    List list =newArrayList<>();

    for(Trade trade : trades) {

    if(trade.getCountry().equals(country)) {

    list.add(trade);

    }

    }

    returnlist;

    }

    ——————————————————————

    好像解决了一部分问题,但老板的需求是无穷无尽的,他万一想知道交易金额大的和交易金额小的交易呢?比如,交易额大于100(w)的交易。你可能会这样做。

    //如果需要又要需要根据交易金额的大小进行筛选.找出大于100万的交易

    public staticList filterTradeByCountry(List trades,doublemoney) {

    List list =newArrayList<>();

    for(Trade trade : trades) {

    if(trade.getMoney() >100) {

    list.add(trade);

    }

    }

    returnlist;

    }

    ————————————————————

    这样虽然满足了需求,但是带来了巨大的问题,大量重复的代码,更为麻烦的是,一个交易重要的字段有很多,如果我们对每个属性都做这样的筛选的话,那么代码会变得非常繁琐,客户端在调用的时候也会更加的麻烦。

    ————————————————————

    行为参数化

    我们现在考虑根据交易的某些属性来返回一个boolen值,比如交易是不是发生在美国,交易金额是不是大于某个数值等等。

    我们将其称为谓词(Predicate,即一个返回boolean值的函数)。定义一个接口:

    public interfaceTradePredicate {

    booleantest(Trade trade);

    }

    现在我们来让filterTrade()方法接收多种行为,也就是这样:

    //filter方法接收多种行为 . 谓词对象封装了Trade的条件,你传递什么进去都可以

    public staticList filterTrade(List trades, TradePredicate predicate) {

    List list =newArrayList<>();

    for(Trade trade : trades) {

    if(predicate.test(trade)) {

    list.add(trade);

    }

    }

    returnlist;

    }

    此时你在main方法中调用的话,就可以怎样做啦!

    List tradeInAmerica =filterTrade(trades,newTradePredicate() {

    @Override

    public booleantest(Trade trade) {

    return"America".equals(trade.getCountry());

    }

    });

    分析一下:TradePredicate是一个谓词,此时我们就把它看作一个行为,在真正去使用它之前,我们并不知道它具体是干什么的。我们在使用它的时候,传递的是一个行为,现在使用的是匿名内部类。

    这就是行为参数化,也就是函数式编程的一个重要的特征。

    不过现在看来,使用匿名内部类的代码仍然看着很烦,放心,Java8很好的为我们解决了这样的一个问题,那就是大名鼎鼎的Lambda表达式。至于什么是Lambda表达式,它有什么样的作用呢,请阅读下一篇博客。Java8函数式编程之二 : Lambda表达式 - 简书 

    ——————————————

    重点笔记:来自《Java8实战》

    行为参数化:一个方法接收多个不同的行为作为参数,并在内部使用它们,完成不同行为的能力。

    行为参数化可以让代码更好的适应不断变化的需求,减轻未来的工作量。

    ————————————————————

    在此推荐 《Java8实战》,此书讲Java8的例子比较浅显易懂。

    相关文章

      网友评论

          本文标题:Java8函数式编程之一: 行为参数化

          本文链接:https://www.haomeiwen.com/subject/znvipxtx.html