Home  >  Article  >  Java  >  Detailed introduction to the sample code of Lambda expression, a new feature of Android using Java 8

Detailed introduction to the sample code of Lambda expression, a new feature of Android using Java 8

黄舟
黄舟Original
2017-03-11 11:54:451890browse

Preface

Lambda expression, a new feature of java8. Using Lambda expression, you can replace the interface implementation with only one function, bid farewell to anonymous inner classes, and the code looks more concise and easy to understand.
java8 also has some other new features, but they may not be available on android.
Studio 2.x and later supports the jack compiler. Using it, you can use the Lambda expression of java8, but there is no guarantee that other features will be available.

Note: The Android SDK integrates some source code of the JDK. Some classes in the native JDK may have some implementations of new features added, but those in Android do not. Another example is the java.util.function package of java8, which is not available in lower versions.

You can also use the plug-in retrolambda to support the Lambda expression of java8.

Jack configuration

Add the following configuration

android {
    jackOptions {
        enabled true
    }
    compileOptions {//jack、retrolambda编译必需        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

to enable the jack compiler to support Lambda expression

Use the latest version 2.3 studio, jdk 1.8 environment, gradle2.3, and the above configuration
After testing, it can also be run on the 4.4 simulator
Configuration Demo: http://www.php.cn/

retrolambda Configuration

retrolambda is compatible with java5, 6, and 7 using Lambda expression.

The configuration is as follows

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'me.tatarka:gradle-retrolambda:3.6.0'
    }}
apply plugin: 'me.tatarka.retrolambda'android {
    defaultConfig {
        minSdkVersion 11 //这个没有硬性要求
    }
    compileOptions {//jack、retrolambda编译必需
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }}

Note: Many open source projects still use retrolambda

How to use Lambda expression

First of all, what we need to know is that the expression as a whole expresses an "Object type".

The simplest Lambda expression

Code:

Runnable runnable = () -> System.out.println("hi, 我是 stone");runnable.run();

() is actually the method parameter list. If no parameters are passed here, then methods without parameters will be matched, so Runnable has only one void run(), so it will be matched; the method name is not written here, so the method name will be ignored.

-> This is followed by the method body. There is only one printing code here, you can omit the curly braces of the method body: {}.

Note: Code such as "new Runnable" is also omitted here because the compiler will perform automatic type inference. If you call () directly -> System.out.println(“hi, I am stone”).run(); then it will not compile because the compiler does not know which class to look for the corresponding method

Lambda expression with parameters and return value

Code:

button.setOnTouchListener((view, event)-> {    
if (event.getAction() == MotionEvent.ACTION_DOWN) {        
if (flag) {            
return true;
        }
    }    return super.onTouchEvent(event);
});

When there are parameters, just pass the parameter name, and the name can be defined at will; the type is defined or not defined Either is OK; if not defined, the compiler will automatically infer it.
When there is a return value, you can use return in the method body; you can also omit return when there is only a piece of code, as follows:

button.setOnTouchListener((v, e) -> super.onTouchEvent(e));

Customize the interface and use Lambda expression

First define an interface with only one abstract method:

    interface IGetData<T> {//lambda只能用于单一方法类型匹配
        T get();//      T getOne(int i); //多个抽象方法,直接编译不过
    }

Define the method, the parameters are the interface defined above:

    void print(IGetData<String> data) {        
    String msg = data.get();        
    System.out.println(msg);
    }

Use Lambda expression as parameter, call print():

        print(() -> "张三");        print(() -> {
            System.out.println("干活了");            return "李四";
        });

Output:

03-08 06:46:00.430 1510-1510/? I/System.out: 张三
03-08 06:46:00.430 1510-1510/? I/System.out: 干活了
03-08 06:46:00.430 1510-1510/? I/System.out: 李四

Use Lambda expression to simplify the commander mode

Features and simple implementation process of the commander mode:

  • A command interface , define an abstract method for uniformly executing commands

  • Each specific commander implements the command interface and relies on a receiver object, and the execution agent of the command is given to the receiver for execution

  • The caller class relies on a command interface object and is executed by the command interface. Polymorphically pass in different specific commanders, and ultimately the receiver adopts different execution methods

Example (original implementation)

For example, there are some file operation commands :open, close, save, delete, the receiver is an editor editor
Then, first, you need to define a command interface: IAction

public interface IAction {//原 命令者  抽象出一个 执行命令的方法
    void perform();
}

and then define four specific command classes OpenAction, CloseAction, SaveAction, and DeleteAction.
CloseAction code:

public class CloseAction implements IAction {
    private Editor mEditor;    
    public CloseAction(Editor editor) {        
    this.mEditor = editor;
    }    
    @Override
    public void perform() {        
    this.mEditor.close();
    }
}

The other three implementations are similar to CloseAction.

Editor class (receiver) defines each specific implementation of the four commands received:

public class Editor {     public void save() {
          System.out.println("save");
      }      public void delete() {
          System.out.println("delete");
      }      public void open() {
          System.out.println("open");
      }      public void close() {
          System.out.println("close");
      }
}

Note: If different editors have their own responses to these commands For different implementations, you can also define an IEditor interface and then implement different Editors. This point will not be discussed in detail

Finally, there is a caller, which can be a class:

public class Invoker {  
    private IAction action;  

    public Invoker(IAction action) {  
        this.action = action;  
    }  

    public void invoke() {  
        this.action.perform();  
    }  
}

client initiates a command:

Editor editor = new Editor();
new Invoker(new OpenAction(editor)).invoke();
new Invoker(new CloseAction(editor)).invoke();
new Invoker(new SaveAction(editor)).invoke();
new Invoker(new DeleteAction(editor)).invoke();

here The caller can be defined not as a class, but as a method in the client:

private void invoke(IAction action) {
    action.perform();
}

client initiates a command call:

 invoke(new OpenAction(editor)); 
 invoke(new CloseAction(editor)); 
 invoke(new SaveAction(editor)); 
 invoke(new DeleteAction(editor));

Lambda expression simplified version

Retain invoke(Iaction action) in IAction, Editor and client.

client initiates a command call:

  Editor editor = new Editor();
  invoke(() -> editor.open());  
  invoke(() -> editor.close());  
  invoke(() -> editor.save());  
  invoke(() -> editor.delete());

In this way, after using Lambda expression, the definition of the specific command class is omitted. And you can see at a glance which method was ultimately executed.

Don’t worry that writing it like this will destroy the original separation of request and execution of the commander mode.
Because invoke(() -> editor.open()); 209861d5cd2975725c730f519ed6ad71

invoke(new IAction() {    @Override
    public void perform() {
        editor.open();
    }
});

If you retain the calling class Invoker, it will be similar to the following call:

new Invoker(() -> editor.open()).invoke();

The above is the detailed content of Detailed introduction to the sample code of Lambda expression, a new feature of Android using Java 8. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn