首页 > 其他 > 详细

函数式编程

时间:2021-01-08 09:26:15      阅读:30      评论:0      收藏:0      [点我收藏+]

Lambda表达式

interface Body {
    String detailed(String head);
}

public class Sample {
    @Test
   public void test_1(){
       Body b= h -> h + " No Parens!";
       System.out.println(b.detailed("1111"));
   }
}

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

OO(object oriented,面向对象)是抽象数据,FP(functional programming,函数式编程)是抽象行为。

任何 Lambda 表达式的基本语法是:

  1. 参数。
  2. 接着 ->,可视为“产出”。
  3. -> 之后的内容都是方法体。
    • [1] 当只用一个参数,可以不需要括号 ()。 然而,这是一个特例。
    • [2] 正常情况使用括号 () 包裹参数。 为了保持一致性,也可以使用括号 () 包裹单个参数,虽然这种情况并不常见。
    • [3] 如果没有参数,则必须使用括号 () 表示空参数列表。
    • [4] 对于多个参数,将参数列表放在括号 () 中。

到目前为止,所有 Lambda 表达式方法体都是单行。 该表达式的结果自动成为 Lambda 表达式的返回值,在此处使用 return 关键字是非法的。 这是 Lambda 表达式简化相应语法的另一种方式。

[5] 如果在 Lambda 表达式中确实需要多行,则必须将这些行放在花括号中。 在这种情况下,就需要使用 return

Lambda 表达式通常比匿名内部类产生更易读的代码,因此我们将在本书中尽可能使用它们。

递归

interface IntCall {
  int call(int arg);
}

public class RecursiveFactorial {
  static IntCall fact;
  public static void main(String[] args) {
    fact = n -> n == 0 ? 1 : n * fact.call(n - 1);
    for(int i = 0; i <= 10; i++)
      System.out.println(fact.call(i));
  }
}

方法引用

方法引用组成:类名或对象名,后面跟 :: [^4],然后跟方法名称。

import java.util.*;

interface Callable { // [1]
  void call(String s);
}

class Describe {
  void show(String msg) { // [2]
    System.out.println(msg);
  }
}

public class MethodReferences {
  static void hello(String name) { // [3]
    System.out.println("Hello, " + name);
  }
  static class Description {
    String about;
    Description(String desc) { about = desc; }
    void help(String msg) { // [4]
      System.out.println(about + " " + msg);
    }
  }
  static class Helper {
    static void assist(String msg) { // [5]
      System.out.println(msg);
    }
  }
  public static void main(String[] args) {
    Describe d = new Describe();
    Callable c = d::show; // [6]
    c.call("call()"); // [7]

    c = MethodReferences::hello; // [8]
    c.call("Bob");

    c = new Description("valuable")::help; // [9]
    c.call("information");

    c = Helper::assist; // [10]
    c.call("Help!");
  }
}

[1] 我们从单一方法接口开始(同样,你很快就会了解到这一点的重要性)。

[2] show() 的签名(参数类型和返回类型)符合 Callablecall() 的签名。

Callable接口是属于Executor框架中的功能类,Callable接口与Runnable接口的功能类似,但提供了比Runnable更加强大的功能。

  • Callable可以在任务结束的时候提供一个返回值,Runnable无法提供这个功能
  • Callable的call方法分可以抛出异常,而Runnable的run方法不能抛出异常。

[3] hello() 也符合 call() 的签名。

[4] help() 也符合,它是静态内部类中的非静态方法。

[5] assist() 是静态内部类中的静态方法。

[6] 我们将 Describe 对象的方法引用赋值给 Callable ,它没有 show() 方法,而是 call() 方法。 但是,Java 似乎接受用这个看似奇怪的赋值,因为方法引用符合 Callablecall() 方法的签名。

[7] 我们现在可以通过调用 call() 来调用 show(),因为 Java 将 call() 映射到 show()

[8] 这是一个静态方法引用。

[9] 这是 [6] 的另一个版本:对已实例化对象的方法的引用,有时称为绑定方法引用

[10] 最后,获取静态内部类中静态方法的引用与 [8] 中通过外部类引用相似。

函数式编程

原文:https://www.cnblogs.com/webzom/p/14248812.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!