Expression Lambda, une nouvelle fonctionnalité de java8. En utilisant l'expression Lambda, vous pouvez remplacer l'implémentation de l'interface par une seule fonction, dire adieu aux classes internes anonymes et le code semble plus concis et facile à comprendre.
Java8 propose également d'autres nouvelles fonctionnalités, mais elles peuvent ne pas être disponibles sur Android.
Studio 2.x et versions ultérieures prennent en charge le compilateur jack. En l'utilisant, vous pouvez utiliser l'expression Lambda de java8, mais rien ne garantit que d'autres fonctionnalités seront disponibles.
Remarque : Le SDK Android intègre du code source du JDK. Certaines classes du JDK natif peuvent avoir des implémentations de nouvelles fonctionnalités ajoutées, mais pas celles d'Android. Un autre exemple est le package java.util.function de java8, qui n'est pas disponible dans les versions inférieures
Vous pouvez également utiliser le plug-in retrolambda pour prendre en charge l'expression Lambda de java8.
Ajoutez la configuration suivante
android { jackOptions { enabled true } compileOptions {//jack、retrolambda编译必需 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
pour permettre au compilateur Jack de prendre en charge l'expression Lambda
Utilisez la dernière version 2.3 studio, environnement jdk 1.8, gradle2.3 et la configuration ci-dessus
Après test, il peut également être exécuté sur le simulateur 4.4
Démo de configuration : //m.sbmmt.com/
retrolambda est compatible avec java5, 6 et 7 en utilisant l'expression Lambda.
La configuration est la suivante
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 }}
Remarque : de nombreux projets open source utilisent encore retrolambda
Tout d'abord, ce qu'il faut savoir, c'est que cette expression dans son ensemble exprime un "type d'objet".
Code :
Runnable runnable = () -> System.out.println("hi, 我是 stone");runnable.run();
() est en fait la liste des paramètres de la méthode. Si aucun paramètre n'est transmis ici, elle correspondra à la méthode sans paramètres. , comme Runnable n'a qu'un seul void run(), il sera mis en correspondance ; le nom de la méthode n'est pas écrit ici, donc le nom de la méthode sera ignoré.
-> Ceci est suivi du corps de la méthode. Il n'y a qu'un seul code d'impression ici, vous pouvez omettre les accolades du corps de la méthode : {}.
Remarque : le code tel que "new Runnable" est également omis ici car le compilateur effectuera une inférence de type automatique. Si vous appelez () directement -> System.out.println(“salut, je suis stone”).run(); alors il ne sera pas compilé car le compilateur ne sait pas dans quelle classe rechercher la méthode correspondante
Code :
button.setOnTouchListener((view, event)-> { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (flag) { return true; } } return super.onTouchEvent(event); });
Quand il y a des paramètres, passez simplement le nom du paramètre, et le nom peut être défini à volonté ; définition de type ou Peu importe s'il n'est pas défini ; lorsqu'il n'est pas défini, le compilateur le déduira automatiquement.
Lorsqu'il y a une valeur de retour, vous pouvez utiliser return dans le corps de la méthode ; vous pouvez également omettre return lorsqu'il n'y a qu'un morceau de code, comme suit :
button.setOnTouchListener((v, e) -> super.onTouchEvent(e));
Définissez d'abord une interface avec une seule méthode abstraite :
interface IGetData<T> {//lambda只能用于单一方法类型匹配 T get();// T getOne(int i); //多个抽象方法,直接编译不过 }
Définissez la méthode, et les paramètres sont l'interface définie ci-dessus :
void print(IGetData<String> data) { String msg = data.get(); System.out.println(msg); }
Utilisez Expression Lambda comme paramètre et appel print() :
print(() -> "张三"); print(() -> { System.out.println("干活了"); return "李四"; });
Sortie :
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: 李四
Caractéristiques et processus de mise en œuvre simple de le modèle de commandant :
Une interface de commande définit une méthode abstraite pour exécuter les commandes de manière uniforme
Chaque commandant spécifique implémente l'interface de commande et s'appuie sur un objet récepteur, commande L'agent d'exécution est donné au récepteur pour exécuter la classe d'appelant
, qui s'appuie sur un objet d'interface de commande et est exécutée par l'interface de commande. Passer polymorphiquement dans différents commandants spécifiques, et finalement le récepteur adopte différentes méthodes d'exécution
Par exemple, il existe des commandes d'opération de fichiers :open, fermer, enregistrer, supprimer, le récepteur est un éditeur éditeur
Eh bien, vous devez d'abord définir une interface de commande : IAction
public interface IAction {//原 命令者 抽象出一个 执行命令的方法 void perform(); }
, puis définir quatre classes de commandes spécifiques OpenAction, CloseAction, SaveAction et DeleteAction.
Code CloseAction :
public class CloseAction implements IAction { private Editor mEditor; public CloseAction(Editor editor) { this.mEditor = editor; } @Override public void perform() { this.mEditor.close(); } }
Les trois autres implémentations sont similaires à CloseAction.
La classe éditeur (récepteur) définit chaque implémentation spécifique de la réception de quatre commandes :
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"); } }
Remarque : si différents éditeurs ont des exigences différentes pour ces commandes, s'il existe différentes implémentations, vous pouvez également définir une interface IEditor puis implémenter différents éditeurs. Ce point ne sera pas abordé en détail
Enfin il y a un appelant, qui peut être une classe :
public class Invoker { private IAction action; public Invoker(IAction action) { this.action = action; } public void invoke() { this.action.perform(); } }
le client initie une commande :
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();
L'appelant ici peut être défini non pas comme une classe, mais comme une méthode dans le client :
private void invoke(IAction action) { action.perform(); }
Le client initie un appel de commande :
invoke(new OpenAction(editor)); invoke(new CloseAction(editor)); invoke(new SaveAction(editor)); invoke(new DeleteAction(editor));
conserve l'invocation (action Iaction) dans IAction, l'éditeur et le client.
le client lance un appel de commande :
Editor editor = new Editor(); invoke(() -> editor.open()); invoke(() -> editor.close()); invoke(() -> editor.save()); invoke(() -> editor.delete());
De cette façon, après avoir utilisé l'expression Lambda, la définition de la classe de commande spécifique est omise. Et vous pouvez voir d’un seul coup d’œil quelle méthode a finalement été exécutée.
Ne vous inquiétez pas, l'écrire ainsi détruira la séparation originale de la demande et de l'exécution du mode commandant.
Parce queinvoke(() -> editor.open()); <==>
invoke(new IAction() { @Override public void perform() { editor.open(); } });
Si vous conservez la classe appelante Invoker, elle sera appelée comme suit :
new Invoker(() -> editor.open()).invoke();
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!