ホームページ  >  記事  >  Java  >  Java 8を使ったAndroidの新機能ラムダ式のサンプルコードを詳しく紹介

Java 8を使ったAndroidの新機能ラムダ式のサンプルコードを詳しく紹介

黄舟
黄舟オリジナル
2017-03-11 11:54:451934ブラウズ

はじめに

Java8の新機能であるラムダ式。 Lambda 式を使用すると、インターフェイスの実装を 1 つの関数だけで置き換えることができ、匿名の内部クラスに別れを告げることができ、コードはより簡潔で理解しやすくなります。
Java8 には他にもいくつかの新機能がありますが、Android では利用できない場合があります。
Studio 2.x 以降では jack コンパイラーがサポートされており、これを使用すると java8 の Lambda 式を使用できますが、他の機能が使用できるという保証はありません。

注: Android SDK には、JDK の一部のソース コードが統合されています。ネイティブ JDK の一部のクラスには、追加された新機能の実装が含まれている場合がありますが、Android のクラスには含まれていません。もう 1 つの例は、java8 の java.util.function パッケージです。これは、以前のバージョンでは使用できません。プラグイン Retrolambda を使用して、java8 の Lambda 式をサポートすることもできます。

ジャック構成

次の構成を追加

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

して、ジャックコンパイラーがラムダ式をサポートできるようにします

最新バージョン2.3スタジオ、jdk 1.8環境、gradle2.3、および上記の構成を使用します

テスト後は、4.4 シミュレーターでも実行できます
構成デモ: http://www.php.cn/



retrolambda 構成

retrolambda は、Lambda 式を使用して Java5、6、および 7 と互換性があります。

構成は次のとおりです

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
    }}

注: 多くのオープンソースプロジェクトは依然として Retrolambda を使用しています

ラムダ式の使用方法

まず第一に、知っておく必要があるのは、式が全体として、 『

オブジェクトタイプ

』。

最も単純な Lambda 式

コード:

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

() は、実際には、ここにパラメータが渡されない場合、Runnable には void run() が 1 つしかないため、パラメータのないメソッドと一致します。ここにはメソッド名が記述されていないため、メソッド名は無視されます。

-> これにメソッド本体が続きます。ここには印刷コードが 1 つだけあり、メソッド本体の中括弧 {} は省略できます。

注: コンパイラーが自動型推論を実行するため、「new Runnable」などのコードはここでは省略されています。 () を直接呼び出すと、 -> System.out.println(“hi, I am stone”).run(); コンパイラは対応するメソッドを探すべきクラスを認識しないため、コンパイルされません

はい、パラメータと戻り値を含むラムダ式です

コード:

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

パラメータがある場合は、パラメータ名を渡すだけです。名前は定義されていない場合は、コンパイラによって定義されます。自動的に推測してくれます。

戻り値がある場合は、メソッド本体で return を使用できます。次のように、コードが 1 つしかない場合は return を省略することもできます:

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

インターフェイスをカスタマイズして Lambda 式を使用します

最初にインターフェイスを定義します抽象メソッドを 1 つだけ使用します:

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

メソッドを定義し、パラメータは上で定義したインターフェイスです:

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

ラムダ式をパラメータとして使用し、print() を呼び出します:

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

出力:

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: 李四

ラムダ式を使用して、コマンダー パターン

コマンダー パターンの特徴と機能 簡単な実装プロセス:

コマンド インターフェイスは、コマンドを均一に実行するための抽象メソッドを定義します
  • それぞれの特定のコマンダーはコマンド インターフェイスを実装し、レシーバー オブジェクトに依存します。コマンドの実行プロキシは受信者に与えられます。
  • 呼び出し元クラスを実行するには、コマンドインターフェースによって実行されるコマンドインターフェースオブジェクトに依存します。 異なる特定のコマンダーをポリモーフィカルに渡し、最終的に受信側は異なる実行方法を採用します
  • 例 (オリジナルの実装)
たとえば、いくつかのファイル操作コマンドがあります: 開く、閉じる、保存、削除、受信側はエディターです

まず、コマンド インターフェイス IAction

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

を定義し、次に 4 つの特定のコマンド クラス OpenAction、CloseAction、SaveAction、および DeleteAction を定義する必要があります。
CloseAction コード:

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

他の 3 つの実装は CloseAction と似ています。

Editor クラス (レシーバー) は、4 つのコマンドを受信するそれぞれの具体的な実装を定義します。

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");
      }
}

注: 異なるエディターにこれらのコマンドの異なる実装がある場合、IEditor をインターフェイスとして定義し、異なるエディターを実装することもできます。この点については詳しくは説明しません

最後に、呼び出し元があります。これはクラスにすることができます:

public class Invoker {  
    private IAction action;  

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

    public void invoke() {  
        this.action.perform();  
    }  
}
クライアントはコマンドを開始します:

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();

ここでの呼び出し元は、クラスを使用する代わりに定義できます。クライアント内:

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

client がコマンド呼び出しを開始します:

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

ラムダ式の簡易バージョン

IAction、エディター、およびクライアントで呼び出し (Iaction アクション) を保持します。

クライアントはコマンド呼び出しを開始します:

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

このように、Lambda式を使用した後、特定のコマンドクラスの定義は省略されます。また、最終的にどのメソッドが実行されたかが一目でわかります。

このように書くと、コマンダーモードのリクエストと実行の本来の分離が破壊されることになるので心配しないでください。

invoke(() -> editor.open()); 209861d5cd2975725c730f519ed6ad71

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

呼び出しクラス Invoker を保持すると、次の呼び出しのようになります:

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

以上がJava 8を使ったAndroidの新機能ラムダ式のサンプルコードを詳しく紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。