preface

Functional programming is now widely used in Java projects. In order to consolidate this knowledge, I will write an article to record my learning experience. Java is not a functional language, but Lambda expressions and method references starting with Java 8 allow us to do functional programming in the Java language.

Usually, passed to the method of data, the result is different, if we hope to behavior of different methods in the call, only need to pass code method, namely the method is passed to the method, it can control the behavior of the method, which is one of functional programming meaning, look at the below Java is how to support the functional programming.

Lambda expressions

Lambda expressions are functions written using the least possible syntax, as shown in the following example:


interface Service {
    String print(String name);
}

class Basketball implements Service {
    @Override
    public String print(String name) {
        return name + "Playing basketball."; }}class People {
    Service service;
    String name;
    People(String name) {
        this.name = name;
    }
    void setService(Service service) {
        this.service = service;
    }
    void process(a) { System.out.println(service.print(name)); }}public class Test {
    public static void main(String[] args) {
        People people = new People("Xiao Ming");
        Service service = new Service() {
            @Override
            public String print(String name) {
                return name + "Playing basketball."; }};/ / 1
        people.setService(service);
        people.process();

        service = new Basketball(); / / 2
        people.setService(service);
        people.process();

        service = (name -> name + "Playing basketball."); / / 3
        people.setService(service);
        people.process();
        
        service = (a -> a + "Playing football."); / / 4people.setService(service); people.process(); }}Copy the code

Output result:

Xiao Ming is playing basketball xiao Ming is playing basketball Xiao Ming is playing basketball Xiao Ming is playing footballCopy the code

The above code implements the same function in three different ways to make an object of type People call its process() method to print out the relevant information.

  1. Create an anonymous inner class with redundant code.
  2. General practice, trouble.
  3. Lambda expression, using Lambda->When the function body has only one line, the return value of the expression is the return value of the function. This achieves the same effect as anonymous inner classes and defined classes, but with much less code.
  4. You can see here->The argument on the left can be named as long as the body of the Lambda function and the return value areServiceThe method body in the interface can be one-to-one correspondence, xiao Ming’s original behavior is playing basketball, now I pass the method of playing football to him, he is playing football, here we transfer is the method, that is, the method as an object to transfer, wonderful ah!

Of course, Lambda expressions have other syntactic variations:


interface Description {
  String brief(a);
}

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

  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()); }}Copy the code

Output result:

Oh! No Parens!
Hi! More details
Short info
Pi! 3.14159
moreLines()
from moreLines(a)

Copy the code
  1. When you use only one parameter, you don’t need parentheses(a)However, this is a special case.
  2. Normally parentheses are used(a)Package parameters. For consistency, parentheses can also be used(a)Wrap a single parameter, although this is not common.
  3. If there are no arguments, parentheses must be used(a)Represents an empty parameter list.
  4. For multiple arguments, place the argument list in parentheses(a)In the. So far, all Lambda expression method bodies have been single lines. The result of this expression automatically becomes the return value of the Lambda expression and is used herereturnThe keyword is illegal. This is another way Lambda expression abbreviations are used to describe the syntax of functionality.
  5. If you really need more than one line in a Lambda expression, you must put those lines in curly braces. In this case, return is needed.

Method references

Method reference syntax: class name or object name :: method name.

interface Service { / / 1
    String print(String name);
}

class Swim { 
    public String swim(String name) { / / 2
        return name + "Swimming"; }}class Jijian {
    public static String jijian(String name) { / / 3
        return name + "Fencing."; }}public class Test {
    public static void main(String[] args) {
        Swim swim = new Swim();
        Service service = swim::swim; / / 4
        System.out.println(service.print("Xiao Ming"));

        service = Jijian::jijian; / / 5
        System.out.println(service.print("Xiao Ming")); }}Copy the code

Output result:

Xiao Ming is swimming and Xiao Ming is fencingCopy the code
  1. Start with a single interface method (there can only be one abstract method in the interface).
  2. swim()The signature (parameter type and return type) of theServiceprint()The signature.
  3. jijian()It will be in.
  4. willSwimObject to which a method reference is assignedServiceIt does notswim()Method, but ratherprint()Method, but Java accepts this seemingly strange assignment because the method reference matches the signature of the function.
  5. Static methods are simply referred to by class names.

Conclusion: OO (Object Oriented) is abstract data, FP (functional programming, functional programming) is abstract behavior.

There is more to Java functional programming than that. This article refers to On Java 8, written by the author of Ideas for Java Programming, and can be found at github.com/kyiree/Ling…