• Lambda


    函数式编程语言操纵代码片段就像操作数据一样容易。 虽然 Java 不是函数式语言,但 Java 8 Lambda 表达式和方法引用 (Method References) 允许你以函数式编程。

     

    新旧对比

    通过下面的案例引入匿名内部类, lambda表达式, 方法引用, 作出对比

     

    // functional/Strategize.java
    
    interface Strategy {
      String approach(String msg);
    }
    
    class Soft implements Strategy {
      public String approach(String msg) {
        return msg.toLowerCase() + "?";
      }
    }
    
    class Unrelated {
      static String twice(String msg) {
        return msg + " " + msg;
      }
    }
    
    public class Strategize {
      Strategy strategy;
      String msg;
      Strategize(String msg) {
        strategy = new Soft();      // [1] 在 Strategize 中,Soft 作为默认策略,在构造函数中赋值。
        this.msg = msg;
      }
    
      void communicate() {
        System.out.println(strategy.approach(msg));
      }
    
      void changeStrategy(Strategy strategy) {
        this.strategy = strategy;
      }
    
      public static void main(String[] args) {
        Strategy[] strategies = {
          new Strategy() {               // [2]创建一个匿名内部类,代码显得比较冗余
            public String approach(String msg) {
              return msg.toUpperCase() + "!";
            }
          },
          msg -> msg.substring(0, 5), // [3]Java8的 Lambda表达式。由箭头 -> 分隔开参数和函数体,
                                        箭头左边是参数,箭头右侧是从Lambda返回的表达式,即函数体。
                                        这实现了与定义类、匿名内部类相同的效果,但代码少得多。
                                            
          Unrelated::twice // [4]Java 8 的方法引用,由 :: 区分。
                             在 :: 的左边是类或对象的名称,在 :: 的右边是方法的名称,但没有参数列表
        };
        Strategize s = new Strategize("Hello there");
        s.communicate();
        for(Strategy newStrategy : strategies) {
          s.changeStrategy(newStrategy); // [5] 在使用默认的 Soft strategy 之后,
                                           我们逐步遍历数组中的所有 Strategy,
                                          并使用changeStrategy()方法将每个Strategy放入变量s中
          s.communicate(); // [6]每次调用 communicate() 都会产生不同的行为,
                           具体取决于此刻正在使用的策略代码对象。我们传递的是行为,而非仅数据
        }
      }
    }

    output:

    hello there?
    
    HELLO THERE!
    
    Hello
    
    Hello there Hello there

    Lambda表达式


    带有参数变量的表达式,是一段可以传递的代码,可以被一次或多次执行

    是一种精简的字面写法,其实就是把匿名内部类中“一定”要做的工作省略掉,然后由JVM通过推导把简化的表达式还原

     

    格式:  (parameters参数) -> expression表达式或方法体

     

    paramaters:

    类似方法中的形参列表,这里的参数是函数式接口里的参数

     

    -> 

    可理解为“被用于”的意思

     

    方法体:

    可以是表达式也可以代码块,是函数式接口里方法的实现

    如果负责运算的代码无法用表达式表示,可以使用编写方法实现

    但必须用{}包围并按需明确使用 return语句

     

     

    // functional/LambdaExpressions.java
    
    interface Description {
      String brief();
    }
    
    interface Body {
      String detailed(String head);
    }
    
    interface Multi {
      String twoArg(String head, Double d);
    }
    
    public class LambdaExpressions {
    
        //当只用一个参数,可以不需要括号 ()
      static Body bod = h -> h + " No Parens!"; // [1]
    
        //正常情况使用括号 () 包裹参数,
        //为了保持一致性,也可以使用括号 ()包裹单个参数,虽然这种情况并不常见。
      static Body bod2 = (h) -> h + " More details"; // [2]。 
                                                          
                                                        
        //如果没有参数,则必须使用括号 () 表示空参数列表
      static Description desc = () -> "Short info"; // [3]
        
        //对于多个参数,将参数列表放在括号 () 中
      static Multi mult = (h, n) -> h + n; // [4]
    
        /**到目前为止,所有 Lambda 表达式方法体都是单行。 
         该表达式的结果自动成为 Lambda 表达式的返回值,在此处使用 return 关键字是非法的。 
         这是 Lambda 表达式缩写用于描述功能的语法的另一种方式。
       */
        
        //如果在 Lambda 表达式中确实需要多行,则必须将这些行放在花括号中。 
        //在这种情况下,就需要使用 return。
      static Description moreLines = () -> { // [5]
        System.out.println("moreLines()");
        return "from moreLines()";
      };
    
      public static void main(String[] args) {
        System.out.println(bod.detailed("Oh!"));
        System.out.println(bod2.detailed("Hi!"));
        System.out.println(desc.brief());
        System.out.println(mult.twoArg("Pi! ", 3.14159));
        System.out.println(moreLines.brief());
      }
    }

    output:

    Oh! No Parens!
    
    Hi! More details
    
    Short info
    
    Pi! 3.14159
    
    moreLines()
    
    from moreLines()
  • 相关阅读:
    在线|九月月考选填题
    函数$f(x)=e^xpm e^{-x}$相关
    偶函数性质的推广
    2020年全国卷Ⅱ卷文科数学选填题解析版
    2020年全国卷Ⅱ卷文科数学解答题解析版
    待定系数法
    特殊方法求函数解析式
    phd文献阅读日志-4.1
    phd文献阅读日志-1.2~3.2(1.2,2.1,2.2,3.1,3.2)
    完美解决linux下vim在终端不能用鼠标复制的问题
  • 原文地址:https://www.cnblogs.com/sanye613/p/13265422.html
Copyright © 2020-2023  润新知