Lambda is introduced

Lambda, alias functional programming, wikipedia provides the following introduction:

Functional programming is a programming paradigm. It treats computation as if it were the evaluation of a mathematical function, thereby avoiding changing states and using mutable data. It is a declarative programming paradigm that programs through expressions and declarations rather than statements.

Lambda expression is named after the Lambda calculus in mathematics. It directly corresponds to the Lambda abstraction. It is an anonymous function, that is, a function without a function name. A Lambda expression can represent a closure (note the difference from the mathematical tradition).

λ calculus is a formal system in mathematical logic, which uses variable binding and substitution to express computation on the basis of function abstraction and application. The discussion of the calculus of λ cannot be separated from the formal expression. In this article, we try to focus on the basic concepts related to programming, rather than getting stuck in mathematical formalization. The calculus of λ is actually a simplification of the previously mentioned concept of functions to facilitate the study of functions in a systematic manner.

In Java Lambda

Since the release of Java8, Java also supports lambda syntax, which makes cumbersome operations before can be replaced by simple syntax. The most representative reform is the new Stream class, which makes it more convenient for us to sort, filter, map and collect a collection!

Let’s draw up a scenario where, given an int array, we filter out the negative numbers and sort the remaining elements. Before java8, our implementation would have to write:

int[] array = {7, -2.3.5, -9.3, -5, -};
List<Integer> list = new ArrayList<Integer>();
// Filter negative numbers
for(int i: array) {
    if(i >= 0) list.add(i);
/ / sorting

for(int i: list) {
Copy the code

After using Stream:

int[] array = {7, -2.3.5, -9.3, -5, -};
    .filter(a -> a >= 0)    / / filter
    .sorted()               / / sorting
Copy the code

As you can see, the implementation process is much more concise and elegant. Lambdas save a lot of code space and improve the readability of the code, but also make it more difficult to use. Lambda syntax is a significant impact on traditional programming methods.

The use of Lambda syntax in Java

Functional interface

What is a functional interface? Before Java8, we wanted to implement an interface, the simplest way to use anonymous classes directly:

Comparator<Integer> comparator = new Comparator<Integer>() {
    public int compare(Integer o1, Integer o2) {
        return o1 > o2 ? 1 : -1; }};Copy the code

If the interface has more than two methods to implement, the interface will be labeled with the @functionalInterface annotation. If the interface has more than two methods to implement, the interface will be labeled with the @functionalInterface annotation. Your IDE will remind you that this is not a formal functional interface, and for those that do, we can initialize them using lambda syntax:

Comparator<Integer> comparator = (o1, o2) -> o1 > o2 ? 1 : -1;
Copy the code

Comparing this to the pre-Java 8 implementation, we find that there are many similarities, so let’s analyze the implementation of lambda:

(o1, o2) -> o1 > o2 ? 1 : -1;
Copy the code

I’m going to divide the top part by ->, and I’m going to divide it into two parts, which are (o1, O2) and o1 > O2, right? 1:1. Obviously, the former represents the two input parameters of the function, and the latter represents the logical implementation of the two input parameters. Thus, a lambda consists of two parts: the input parameter definition and the logical implementation.

For a functional interface, we can use simple lambda syntax to implement the only method to be implemented in the interface. To backtrack, for anonymous function definition style like lambda, if an interface has two methods to be implemented, lambda cannot specify which method is implemented. A functional interface can have at most one method to implement.

JDK support for Lambda

We know a simple form of the lambda syntax through the definition of a functional interface and the implementation of a lambda. However, in the development process, it is impossible to define a functional interface for every application of a lambda. In fact, many lambda functions already exist in the JDK:

  • Function<T, R>: Takes a parameter input of type T and type R. The abstract method isR apply(T).
  • BiFunction<T, U, R>: Takes two parameter inputs, T and U are the types of the two parameters, and R is the output type. The abstract method isR apply(T, U).
  • Consumer: Accepts an input, no output. The abstract method isvoid accept(T t).
  • Predicate: Takes an input and outputs a Boolean type. The abstract method isboolean test(T t).
  • Supplier: No input, one output. The abstract method isT get().
  • BinaryOperator: accepts two inputs of the same type and outputs the same type as the input, equivalent to BiFunction

  • UnaryOperator: Takes an input and outputs the same type as the input, equivalent to Function

  • BiPredicate

    : Accepts two inputs, and the output is Boolean. The abstract method is Boolean test(T T, U U).

They apply to different scenarios, and here are a few examples, starting with implementing a calculator using lambda:

BinaryOperator<Integer> cal = (a, b) -> a + b;
System.out.println(bo.apply(1.2)); / / 3
Copy the code

Here’s another one, using lambda for positive or negative numbers

int a = 1;
int b = -1;
Predicate<Integer> predicate =  i -> i >= 0;
System.out.println(predicate.test(a));  //true
System.out.println(predicate.test(b));  //false
Copy the code


In Stream, lambda has a wide range of applications. If we want to master lambda more skillfully, we need to use lambda personally and truly appreciate its power in actual combat.

Refer to the article

  • In-depth understanding of Java functional programming
  • The Streams API in Java 8
  • Baidu Encyclopedia — Lambda expressions