functional programming - Method References

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangbingfengf98/article/details/86550446

Java 8 Method References refer to methods without the extra baggage required by previous versions of Java. A method reference is a class name or an object name, followed by a ::, then the name of the method.

Java 8 allows four types of method references.

METHOD REFERENCE DESCRIPTION METHOD REFERENCE EXAMPLE
Reference to static method Used to refer static methods from a class Math::max equivalent to Math.max(x,y)
Reference to instance method from instance Refer to an instance method using a reference to the supplied object System.out::println equivalent to System.out.println(x)
Reference to instance method from class type Invoke the instance method on a reference to an object supplied by the context String::length equivalent to str.length()
Reference to constructor Reference to a constructor ArrayList::new equivalent to new ArrayList()

// functional/MethodReferences.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

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!");
  }
}
/* Output:
call()
Hello, Bob
valuable information
Help!
*/

[6] We assign a method reference for the Describe object to a Callable—which doesn’t have a show() method but rather a call() method. However, Java seems fine with this seemingly-odd assignment, because the method reference is signature-conformant to Callable ’s call() method.

[7] We can now invoke show() by calling call() , because Java maps call() onto show() .

Runnable

// functional/RunnableMethodReference.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Method references with interface 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();
  }
}
/* Output:
Anonymous
lambda
Go::go()
*/

Unbound Method References

An unbound method reference refers to an ordinary (non-static) method, without an associated object. To apply an unbound reference, we must supply the object: 

// functional/UnboundMethodReference.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Method reference without an object

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; // [1] // compile error, non-static method f() cannot be referenced
    // from a static context
    TransformX sp = X::f; // [3]
    X x = new X();
    System.out.println(sp.transform(x)); // [2]
    System.out.println(x.f()); // Same effect
  }
}
/* Output:
X::f()
X::f()
*/

change class X's method make() to static, uncomment [1], comment [2] [3], the output is same.

// functional/MultiUnbound.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Unbound methods with multiple arguments

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');
  }
}

Constructor Method References

// functional/CtorReference.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

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(); // functional method
}

interface Make1Arg {
  Dog make(String nm);  // functional method
}

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

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);
  }
}

references:

1. On Java 8 - Bruce Eckel

2. https://howtodoinjava.com/java8/lambda-method-references-example/

3. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/MethodReferences.java

4. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/RunnableMethodReference.java

5. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/MultiUnbound.java

猜你喜欢

转载自blog.csdn.net/wangbingfengf98/article/details/86550446