Java foundation papers expression -Lambda

Functional Programming 1. Introduction

Function .png

In mathematics, there is a function of the amount of input, output of a calculation program, which is "to do something to get something." In contrast, object oriented over

Much emphasis on "the object must be done in the form of things," and try to ignore the idea of ​​functional object-oriented complex 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 codes Runnable

  • Traditional writing:

    // 当需要启动一个线程去完成任务时,通常会通过 java.lang.Runnable 接口来定义任务内容,并使用 java.lang.Thread 类来启动该线程。代码如下:
    public class Demo01Runnable { 
        public static void main(String[] args) { 
            // 匿名内部类 
            Runnable task = new Runnable() { 
                @Override 
                public void run() {
                  // 覆盖重写抽象方法 
                  System.out.println("多线程任务执行!");
                } 
            };
            new Thread(task).start(); // 启动线程 
        }
    }
    // 本着“一切皆对象”的思想,这种做法是无可厚非的:首先创建一个 Runnable 接口的匿名内部类对象来指定任务内 容,再将其交给一个线程来启动。
  • Code analysis:

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

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 this and had 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.

    That 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

    Traffic .png

    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.

    traffic

    ​ 而现在这种飞机(甚至是飞船)已经诞生:2014年3月Oracle所发布的Java 8(JDK 1.8)中,加入了Lambda表达式的重量级新特性,为我们打开了新世界的大门。

4. 体验Lambda的更优写法

​ 借助Java 8的全新语法,上述 Runnable 接口的匿名内部类写法可以通过更简单的Lambda表达式达到等效:

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

​ 这段代码和刚才的执行效果是完全一样的,可以在1.8或更高的编译级别下通过。从代码的语义中可以看出:我们启动了一个线程,而线程任务的内容以一种更加简洁的形式被指定。

​ 不再有“不得不创建接口对象”的束缚,不再有“抽象方法覆盖重写”的负担,就是这么简单!

5. Lambda标准格式

  • Lambda省去面向对象的条条框框,格式由3个部分组成:
    1. 一些参数
    2. 一个箭头
    3. 一段代码
  • 标准格式: (参数类型 参数名称) ‐> { 代码语句 }
  • 格式说明:
    1. 小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
    2. -> 是新引入的语法格式,代表指向动作。
    3. 大括号内的语法与传统方法体要求基本一致。

6. 练习1:无参数无返回值的代码

  • 题目

    • 给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:

    • 代码:

      public interface Cook { void makeFood(); }
      // 在下面的代码中,请使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”字样:
      public class Demo05InvokeCook { 
          public static void main(String[] args) { 
              // TODO 请在此使用Lambda【标准格式】调用invokeCook方法 
          }
          private static void invokeCook(Cook cook) { 
              cook.makeFood(); 
          } 
      }
  • 解答:

    invokeCook(() ‐> { System.out.println("吃饭啦!"); });

7. 练习2:有参数有返回值的代码

  • 题目:使用数组存储多个Person对象对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序

    下面举例演示 java.util.Comparator<T>接口的使用场景代码,其中的抽象方法定义为:

    • public abstract int compare(T o1, T o2);

    当需要对一个对象数组进行排序时, Arrays.sort 方法需要一个 Comparator接口实例来指定排序的规则。假设有一个 Person 类,含有 String name 和 int age 两个成员变量:

    public class Person { 
        private String name; 
        private int age; 
        // 省略构造器、toString方法与Getter Setter 
    }
  • 传统方式:

    public class Test {
      public static void main(String[] args) {
        // 本来年龄乱序的对象数组
        Person[] array = {
                new Person("古力娜扎", 19),
                new Person("迪丽热巴", 18),
                new Person("马尔扎哈", 20)
        };
        // 排序
        Arrays.sort(array, new Comparator<Person>() {
          @Override
          public int compare(Person o1, Person o2) {
            return o1.getAge() - o2.getAge();
          }
        });
        // 打印
        for (int i = 0; i < array.length; i++) {
          System.out.println(array[i].getName() + "---" + array[i].getAge());
        }
      }
    }
    
    // 这种做法在面向对象的思想中,似乎也是“理所当然”的。其中 Comparator 接口的实例(使用了匿名内部类)代表 了“按照年龄从小到大”的排序规则。
  • 代码分析:下面我们来搞清楚上述代码真正要做什么事情。

    1. For sorting, Arrays.sort method requires collation, i.e. Comparator interface instance, compare the key abstract methods;
    2. In order to compare the method specified body, we have a need to implement Comparator interface class;
    3. In order to save the trouble definition of a ComparatorImpl implementation class, we had to use anonymous inner classes;
    4. Must be overwritten abstract compare methods, the method name, method parameters, method return values ​​have to write again, and can not be wrong;
    5. In fact, only the body is the key parameters and methods.
  • Lambda way:

    public class Test {
      public static void main(String[] args) {
        // 本来年龄乱序的对象数组
        Person[] array = {
                new Person("古力娜扎", 19),
                new Person("迪丽热巴", 18),
                new Person("马尔扎哈", 20)
        };
        // 排序
        Arrays.sort(array,(Person o1, Person o2) ->{
          return o1.getAge()-o2.getAge();
        });
        // 打印
        for (int i = 0; i < array.length; i++) {
          System.out.println(array[i].getName() + "---" + array[i].getAge());
        }
      }
    }

8. Lambda omitted format

Can be derived can be omitted.

  • Omit rules:

    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.
  • Code:

    // 【练习2代码:】
    // 省略前
        Arrays.sort(array,(Person o1, Person o2) ->{
          return o1.getAge()-o2.getAge();
        });
    // 省略后
        Arrays.sort(array,(o1, o2) ->return o1.getAge()-o2.getAge());

9. 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 the interface and only requires an 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 "interface function."

Guess you like

Origin www.cnblogs.com/bruce1993/p/11847934.html