Talking about functional programming

  1. Get to know the functional interface

First introduce the functional interface. A functional interface is an interface that has and only one abstract method (there can be multiple non-abstract methods). Common functional interfaces include Runnable, Comparable, etc.

@FunctionalInterface
public interface Runnable {
    
    
    void run();
}

public interface Comparable<T> {
    
    
    int compareTo(T var1);
}

After jdk1.8, common functional interfaces (Function, Consumer, Predicate, Supplier, BiFunction, IntBinaryOperator) and their derivative functional interfaces under the java.util.function package have been added.

public interface Consumer<T> {
    
    
    void accept(T var1);
}

public interface Function<T, R> {
    
    
    R apply(T var1);
}

public interface Predicate<T> {
    
    
    boolean test(T var1);
}

public interface Supplier<T> {
    
    
    T get();
}

public interface BiFunction<T, U, R> {
    
    
    R apply(T var1, U var2);
}

public interface IntBinaryOperator {
    
    
    int applyAsInt(int var1, int var2);
}

The above functional interfaces all use generics, the difference lies in the method signature. Therefore, this article only uses the first two functional interfaces as examples. The other principles are similar. First, take Function as an example:

public class FunctionClient {
    
    
    String clientPrint() {
    
    
        return "this is functionClient test";
    }

    public static void main(String[] args) {
    
    
        FunctionInterface functionInterface = new FunctionInterface();
        //第一种写法
        System.out.println(functionInterface.functionTest(FunctionClient::clientPrint));
        //第二种写法
        System.out.println((String) functionInterface.functionTest(functionClient -> functionClient.clientPrint()));
    }
}

class FunctionInterface {
    
    
    FunctionClient functionClient = new FunctionClient();
    <R> R functionTest(Function<FunctionClient, R> function) {
    
    
        return function.apply(functionClient);
    }
}

The functional interface used here is Function, which corresponds to the apply method. The FunctionTest in the FunctionalInterface class is used to simulate the interface that SDK developers give to software developers. The input parameter of this interface is Function, and the output parameter is R:

<R> R functionTest(Function<FunctionClient, R> function) {
    
    
    return function.apply(functionClient);
}

When the function object calls the apply method, it actually executes the code behind the arrow, which is functionClient.clientPrint(). The input parameter of functionTest is the expression "functionClient -> functionClient.clientPrint())". The type executed on the right side of the arrow is the return value type of the functional interface. Since functionClient.clientPrint() returns String, so here is R Also specifically refers to the String type.

In addition to the FunctionClient object specified above, is it possible to use ordinary types instead of the FunctionClient class on the left side of the arrow?

public class FunctionClient {
    
    
    String clientPrint() {
    
    
        return "this is functionClient test";
    }

    public static void main(String[] args) {
    
    
        FunctionInterface functionInterface = new FunctionInterface();
        Function<String, String> function = "This is left param." -> new FunctionClient().clientPrint();//报错行
        System.out.println(functionInterface.functionTest(function));
    }
}

class FunctionInterface {
    
    
    <R> R functionTest(Function<String, R> function) {
    
    
        return function.apply("This is FunctionalInterface");
    }
}

The above code will fail to compile because Function cannot accept String type and other constants. Since the left side of the arrow represents the input parameter of a method, the input parameter can only be a variable for the method, so an error will be reported if it is directly defined as a constant.

So how to represent a scene without parameters? Just define an undeclared variable on the left side of the arrow:

Function<String, String> function = s -> new FunctionClient().clientPrint();

For the assignment of a functional interface, the left side of the arrow only needs to pass in the corresponding number of non-assigned variable names. If there is no input parameter, just use ().

If there is only a return value and no parameters, you can use the Supplier interface:

public class FunctionClient {
    
    
    String clientPrint() {
    
    
        return "this is functionClient test";
    }

    public static void main(String[] args) {
    
    
        FunctionInterface functionInterface = new FunctionInterface();
        Supplier<String> function = () -> new FunctionClient().clientPrint();
        System.out.println(functionInterface.functionTest(function));
    }
}

class FunctionInterface {
    
    
    <R> R functionTest(Supplier<R> function) {
    
    
        return function.get();
    }
}
  1. What are the advantages of functional programming?

Simplify the code, such as:

Runnable runnable1 = new Runnable() {
    
    
    @Override
    public void run() {
    
    
        System.out.println("Runnable");
    }
};

//第一次简化,函数式编程(语句lambda形式)
Runnable runnable2 = () -> {
    
    
    System.out.println("Runnable");
};

//第二次简化,函数式编程(表达式lambda形式)
Runnable runnable3 = () -> System.out.println("Runnable");

又比如:

Consumer<Integer> consumer = i -> System.out.println(i);
List<Integer> arrayList = new ArrayList<>(){
    
    
    {
    
    
        add(1);
        add(2);
        add(4);
    }
};
arrayList.forEach(consumer);
  1. The relationship between lambda, functional programming and callbacks

1. Lambda is an implementation of a functional interface, which can be understood as syntactic sugar.
2. Callback has no limit on the number of methods in the interface, but functional interfaces can only specify one abstract method.
3. The method definitions of functional programming and callback are both on the caller, and the inputs of both are interfaces, but one of them is a normal interface and the other is a functional interface.
4. Functional programming and callback methods are both executed on the callee. The former executes the only corresponding method, such as apply, while the latter may correspond to multiple methods, just execute the corresponding method.
5. Both can use lambda to define method implementation on the caller.
6. The implementation of functional programming is a special callback.

Guess you like

Origin blog.csdn.net/weixin_48968045/article/details/113148594