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.
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 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
First of all, what we need to know is that the expression as a whole expresses an "Object type".
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
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));
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: 李四
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
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));
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!