Java object-oriented (xv)

Lambda expressions

1. Overview of functional programming ideas

In mathematics, a function is to have input, output of a calculation program, which is "to do something to get something." In contrast, the object-oriented too much emphasis on "the object must be done in the form of things," and try to ignore the idea of functional complexity of object-oriented syntax, emphasize what to do, rather than what form do .

Object-oriented thinking:

  • Do one thing, looking for a target to solve this matter, call the object's method to get things done.

Functional programming ideas:

  • As long as get to the results, who do, how to do is not important, important is the result, not pay attention to the process.

2. redundant code

[Example 1] Traditional wording

When you need to start a thread to complete the task, the task is usually defined by the content java.lang.Runnable interface and uses java.lang.Thread class to start the thread. code show as below:

public class DemoRunnable {
    public static void main(String[] args) {
        // 匿名内部类
        Runnable task = new Runnable() {
            @Override
            public void run() { // 覆盖重写抽象方法
                System.out.println("多线程任务执行!");
            }
        };
        new Thread(task).start(); // 启动线程
    }
}

In the "everything is an object," the idea of ​​this approach is understandable: first create an anonymous inner class object Runnable interface to specify the contents of the task, and then handed over to a thread to start.

[Example 1] Analysis Code

For the use of anonymous inner class Runnable, you can analyze several points:

  • Thread class needed Runnable interface as a parameter, wherein the method is run abstract core thread used to specify contents of the task;
  • To run the Specify a body, we have the need to achieve Runnable interface class;
  • To save the trouble to define a RunnableImpl implementation class, we had to use anonymous inner classes;
  • It overwrites the abstract must run method, so the method name, method parameters, method return values have to write again, and can not be wrong;
  • In fact, it seems the key is the only method body .

[Example 2] Traditional wording

When you need a custom sort TreeSet collection, usually defined by the interface jjava.util.Comparator sorting method, and use TreeSet (Comparator <? Super E> comparator) this constructor to call. code show as below:

public class DemoComparator {
    public static void main(String[] args) {
        // 匿名内部类
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) { // 覆盖重写抽象方法
                return Integer.compare(o1, o2);
            }
        };
        
        TreeSet<Integer> set = new TreeSet<>(comparator);
    }
}

[Example 2] Analysis Code

For anonymous inner classes use comparator, and can analyze several points:

  • TreeSet require a comparator that is configured as a parameter, wherein the core is an abstract method to compare the specified sort;
  • In order to compare the specified method body, we have required interface implementation class comparator;
  • In order to save the trouble definition of a comparatorImpl implementation class, we had to use anonymous inner classes;
  • Must be overwritten abstract compare methods, the method name, method parameters, method return values have to write again, and can not be wrong;
  • In fact, only the parameters and method body is the key .

3. Conversion programming ideas

What to do, rather than how to do

We really want to create an anonymous inner class object? Do not. We just to do it and have to create an object. We really hope to do is: pass code to run vivo Thread class known.

Passing a piece of code - this is our real purpose. And create objects only limited by way of a means of object-oriented syntax and had to be taken. Well, there is no simpler way? If we focus from "how to do" return to the "what" of the essence, as long as you will find better able to achieve their goals, process and form does not really matter.

Living example

When we need from Beijing to Shanghai, you can choose high-speed rail, car, cycling or walking. Our real purpose is to reach Shanghai, Shanghai and how to get the form is not important, so we have been exploring there is no better way than the high iron - fly.

And now this aircraft (or even a spaceship) has been born: March 2014 Oracle released Java in 8 (JDK 1.8), adding Lambda expressions heavyweight new features, as we opened the door to a new world.

4. a better experience Lambda wording

With the new syntax for Java 8, the above examples of anonymous inner classes can reach the equivalent of writing a simpler Lambda expressions:

public class DemoLambdaRunnable {
    public static void main(String[] args) {
        new Thread(() -> System.out.println("多线程任务执行!")).start(); // 启动线程
    }
}

public class DemoLambdaComparator {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<>((x, y) -> Integer.compare(x, y));
    }
}

And implementation of the results of this code is just exactly the same, at 1.8 by the compiler level or higher.

There are no longer bound "had to create an interface object", no longer have the burden of "abstract methods overwritten", is that simple!

5. Recalling anonymous inner classes

Lambda is how to defeat the object-oriented? In the example above, the core code is only shown in the following:

() -> System.out.println("多线程任务执行!");

(x, y) -> Integer.compare(x, y);

In order to understand the semantics of Lambda, we need to start from the traditional codes.

A class that implements

To start a thread, we need to create a Thread class object and call start method. In order to specify the content of the thread execution, call the Thread class constructor:

  • public Thread(Runnable target)

In order to obtain an object that implements Runnable interface may implement a class interface definition for RunnableImpl:

public class RunnableImpl implements Runnable {
    @Override
    public void run() {
        System.out.println("多线程任务执行!");
    }
}

Then create an object of the implementation class as the Thread class constructor parameters:

public class Demo03ThreadInitParam {
    public static void main(String[] args) {
        Runnable task = new RunnableImpl();
        new Thread(task).start();
    }
}

[Example 2] are sorted TreeSet Similarly, not described herein.

The use of anonymous inner classes

This RunnableImpl class just to achieve Runnable interface exists, and only used the only time, so the use of anonymous inner class syntax to omit a separate class definition, that anonymous inner classes:

public class Demo04ThreadNameless {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("多线程任务执行!");
            }
        }).start();
    }
}

The benefits and drawbacks of an anonymous inner class

On the one hand, an anonymous inner classes can help us to omit define the implementation class ; on the other hand, the syntax of anonymous inner classes - indeed too complicated!

Semantic Analysis

Careful analysis of the semantics of the code, only the definition of a run method of Runnable interface:

  • public abstract void run();

That is, to develop a program to do things (in fact, a function):

  • No argument : without any conditions to implement the program.
  • None Return Value : This scheme does not produce any results.
  • Code block (Method): Any specific step of the program.

The same semantic reflected in the Lambda syntax, to be more simple:

() -> System.out.println("多线程任务执行!")
  • Front of a pair of parentheses i.e. runparameters of the method (no), who do not need any condition;
  • Intermediate arrows represent a parameter to be passed in front of the code behind;
  • I.e. behind the business logic code output statement.

6. Lambda standard format

Lambda omitted object-oriented rules, and format consists of three parts : the

  • Some parameters
  • An arrow
  • A piece of code

Lambda expressions are a standard format as follows:

(参数类型 参数名称) -> { 代码语句 }

Format Description:

  • Syntax conventional method parameter list in parentheses consistent: the parameter for empty; multiple parameters are separated by commas.
  • -> is the new syntax introduced, on behalf of pointing action.
  • Syntax body in the conventional method requires consistent braces.

7. Lambda omitted format

Can be derived can be omitted

Lambda emphasized that "what" rather than "how to do", according to the information so that both can be deduced that context, can be omitted.

Elliptical Rules

On the basis of the standard format Lambda, omitted rules used for wording:

  1. Type parameter within parentheses may be omitted;
  2. If the parentheses and only one parameter , the parentheses may be omitted;
  3. If the braces and only one statement , regardless of whether there is a return value, you can omit the braces, return keywords and semicolons.

8. Lambda use premise

Lambda syntax is very simple, there is no object-oriented complex constraints. But there are several issues that need special attention when using:

(1) using a Lambda must have an interface, and required interface and only one abstract method . Whether JDK built Runnable, Comparator interfaces or custom interfaces, only when there is an abstract interface methods and only when, can use Lambda.

(2) using a Lambda must be inferred context . The method is a local variable or argument type must Lambda corresponding interface type to use as an example of the Lambda interface.

Note: There is only one interface and abstract method, referred to as " function interface ."

9. Exercise

(1) None None Return parameter

topic

Cook cook a given interface contains only abstract methods makeFood, no parameters and returns no value. as follows:

public interface Cook {
    void makeFood();
}

In the following code, use the Lambda standard format calls invokeCook method, print out "to eat it!" The words:

public class DemoInvokeCook {
    public static void main(String[] args) {
        // 请在此使用Lambda【标准格式】调用invokeCook方法
    }

    private static void invokeCook(Cook cook) {
        cook.makeFood();
    }
}

answer

public static void main(String[] args) {
    invokeCook(() -> {
        System.out.println("吃饭啦!");
    });
}

Note: Parentheses parameters Cook Interface makeFood abstract approach represents is empty, the method braces on behalf of makeFood body.

(2) return a reference

topic

Given a calculator Calculator interface calc containing abstract methods may be obtained by adding the two numbers and int values:

public interface Calculator {
    int calc(int a, int b);
}

In the following code, use the Lambda standard format calls invokeCalc method, is calculated by adding the completion of 120 and 130:

public class Demo08InvokeCalc {
    public static void main(String[] args) {
        // 请在此使用Lambda【标准格式】调用invokeCalc方法来计算120+130的结果
    }

    private static void invokeCalc(int a, int b, Calculator calculator) {
        int result = calculator.calc(a, b);
        System.out.println("结果是:" + result);
    }
}

answer

public static void main(String[] args) {
    invokeCalc(120, 130, (int a, int b) -> {
        return a + b;
    });
}

Note: The parentheses represents the Calculator interface parameters calc abstract method, the method body braces on behalf of the calc.

Guess you like

Origin www.cnblogs.com/xzh0717/p/11334866.html