java8 lambda

话不多说,看看箭头方法->实现的策略模式加减乘除。

第一个策略接口
@FunctionalInterface
public interface Operation {
    double apply(double a, double b);
}

具体实现

public class Calculator {
    // 加法策略
    public static final Operation ADD = (a, b) -> a + b;
    
    // 减法策略
    public static final Operation SUBTRACT = (a, b) -> a - b;
    
    // 乘法策略
    public static final Operation MULTIPLY = (a, b) -> a * b;
    
    // 除法策略
    public static final Operation DIVIDE = (a, b) -> {
        if (b == 0) {
            throw new ArithmeticException("Cannot divide by zero");
        }
        return a / b;
    };
}
  • 当只用一个参数,可以不需要括号 ()。 然而,这是一个特例。
  • 正常情况使用括号 () 包裹参数。 为了保持一致性,也可以使用括号 () 包裹单个参数,虽然这种情况并不常见。
  • 如果没有参数,则必须使用括号 () 表示空参数列表。
  • 对于多个参数,将参数列表放在括号 () 中。

使用策略模式

public class Context {
    private Operation operation;

    public void setOperation(Operation operation) {
        this.operation = operation;
    }

    public double executeOperation(double a, double b) {
        return operation.apply(a, b);
    }
}

测试

public class Main {
    public static void main(String[] args) {
        Context context = new Context();

        // 测试加法
        context.setOperation(Calculator.ADD);
        System.out.println("10 + 5 = " + context.executeOperation(10, 5));

        // 测试减法
        context.setOperation(Calculator.SUBTRACT);
        System.out.println("10 - 5 = " + context.executeOperation(10, 5));

        // 测试乘法
        context.setOperation(Calculator.MULTIPLY);
        System.out.println("10 * 5 = " + context.executeOperation(10, 5));

        // 测试除法
        context.setOperation(Calculator.DIVIDE);
        System.out.println("10 / 5 = " + context.executeOperation(10, 5));

        // 测试除以零
        try {
            System.out.println("10 / 0 = " + context.executeOperation(10, 0));
        } catch (ArithmeticException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}
递归:整数 n 的阶乘
// functional/IntCall.java

interface IntCall {
  int call(int arg);
}


// functional/RecursiveFactorial.java

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));
  }
}
Fibonacci 序列
// functional/RecursiveFibonacci.java

public class RecursiveFibonacci {
  IntCall fib;

  RecursiveFibonacci() {
    fib = n -> n == 0 ? 0 :
               n == 1 ? 1 :
               fib.call(n - 1) + fib.call(n - 2);
  }

  int fibonacci(int n) { return fib.call(n); }

  public static void main(String[] args) {
    RecursiveFibonacci rf = new RecursiveFibonacci();
    for(int i = 0; i <= 10; i++)
      System.out.println(rf.fibonacci(i));
  }
}
方法引用。类名或对象名,后面跟::,然后跟方法名称。
// functional/MethodReferences.java

import java.util.*;

interface Callable { // [1]从单一方法接口开始
  void call(String s);
}

class Describe {
  void show(String msg) { // [2](参数类型和返回类型)符合 **Callable** 的 `call()` 的签名。
    System.out.println(msg);
  }
}

public class MethodReferences {
  static void hello(String name) { // [3]也符合 `call()` 的签名。
    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();
//我们将 **Describe** 对象的方法引用赋值给 **Callable** ,它没有 `show()` 方法,而是 //`call()` 方法。 但是,Java 似乎接受用这个看似奇怪的赋值,因为方法引用符合 **Callable** 的 //`call()` 方法的签名。
    Callable c = d::show; 
    c.call("call()"); //我们现在可以通过调用 `call()` 来调用 `show()`,因为 Java 将 `call()` 映射到 `show()`。

    c = MethodReferences::hello; // 这是一个**静态**方法引用。
    c.call("Bob");

    c = new Description("valuable")::help; // 对已实例化对象的方法的引用,有时称为*绑定方法引用*。
    c.call("information");

    c = Helper::assist; // [10]获取静态内部类的方法引用的操作
    c.call("Help!");
  }
}
Runnable run接口无参数,无返回值
// functional/RunnableMethodReference.java

// 方法引用与 Runnable 接口的结合使用

class Go {
  static void go() {
    System.out.println("Go::go()");
  }
}

public class RunnableMethodReference {
  public static void main(String[] args) {

    new Thread(new Runnable() {
      public void run() {
        System.out.println("Anonymous");
      }
    }).start();

    new Thread(
      () -> System.out.println("lambda")
    ).start();

    new Thread(Go::go).start();
  }
}
未绑定的方法引用

未绑定的方法引用是指没有关联对象的普通(非静态)方法。使用未绑定的引用之前,我们必须先提供对象。

// functional/UnboundMethodReference.java

// 没有方法引用的对象

class X {
  String f() { return "X::f()"; }
}

interface MakeString {
  String make();
}

interface TransformX {
  String transform(X x);
}

public class UnboundMethodReference {
  public static void main(String[] args) {
    // MakeString ms = X::f; //该方法不是静态方法,只是普通的成员方法,并且还没有绑定对象,所以错误
    TransformX sp = X::f;//声明传入的参数调用了X类型的f方法代码。
    X x = new X();  //参数
    System.out.println(sp.transform(x)); // sp调用方法
    System.out.println(x.f()); // 同等效果
  }
}

未绑定的方法与多参数的结合运用

class This {
  void two(int i, double d) {}
  void three(int i, double d, String s) {}
  void four(int i, double d, String s, char c) {}
}

interface TwoArgs {
  void call2(This athis, int i, double d);
}

interface ThreeArgs {
  void call3(This athis, int i, double d, String s);
}

interface FourArgs {
  void call4(
    This athis, int i, double d, String s, char c);
}

public class MultiUnbound {
  public static void main(String[] args) {
    TwoArgs twoargs = This::two;
    ThreeArgs threeargs = This::three;
    FourArgs fourargs = This::four;
    This athis = new This();
    twoargs.call2(athis, 11, 3.14);
    threeargs.call3(athis, 11, 3.14, "Three");
    fourargs.call4(athis, 11, 3.14, "Four", 'Z');
  }
}
构造函数的引用

class Dog {
  String name;
  int age = -1; // For "unknown"
  Dog() { name = "stray"; }
  Dog(String nm) { name = nm; }
  Dog(String nm, int yrs) { name = nm; age = yrs; }
}

interface MakeNoArgs {
  Dog make();
}

interface Make1Arg {
  Dog make(String nm);
}

interface Make2Args {
  Dog make(String nm, int age);
}

public class CtorReference {
  public static void main(String[] args) {
    MakeNoArgs mna = Dog::new; // [1]
    Make1Arg m1a = Dog::new;   // [2]
    Make2Args m2a = Dog::new;  // [3]

    Dog dn = mna.make();
    Dog d1 = m1a.make("Comet");
    Dog d2 = m2a.make("Ralph", 4);
  }
}

Dog 有三个构造函数,函数接口内的 make() 方法反映了构造函数参数列表( make() 方法名称可以不同)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值