Skip to content

Latest commit

 

History

History
97 lines (71 loc) · 2 KB

lambda.md

File metadata and controls

97 lines (71 loc) · 2 KB

Lambda λ

一種簡化寫 callback 的表達式。

Before:

view.setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View v) {
    println("yo");
  }
});

After:

view.setOnClickListener(v -> System.out.println(v));

or

view.setOnClickListener(System.out::println);
  • 當 interface 只有一個 method 需要實作時,就不需要特別再說是哪個 method name 了。包含 interface name 就可以整個省略。只剩下參數名稱要寫而已,如果怕參數型別有混淆之虞可寫上型別:
view.setOnClickListener((View v) -> println(v));
  • 如果沒有參數:

Before:

Runnable run = new Runnable() {
  @Override public void run() {
    println("yo");
  }
};

After:

Runnable run = () -> println("yo");

如果你要在 Android 上使用,請參考 gradle-retrolambda

進階:如果 abstract class 只有一個 abstract method 是否也能適用 lambda?

筆者測試過,目前是不行的。

這裡筆者有想到一招替代方案,寫個可以吃 lambda 的 abstract class creator 來幫忙生,例如:

Before:

void save(ParseUser user) {
    // SaveCallback 是 abstract class 且只有一個 abstract method: "void done(ParseException e);"
    user.save(new SaveCallback() {
        @Override public void done(ParseException e) {
            e.printStackTrace();
        }
    });
}

After:

void save(ParseUser user) {
    user.save(Callbacks.save(e -> e.printStackTrace()));
}

寫一個可以吃 lambda 的 Callbacks.save() 來幫忙生 abstract SaveCallback:

public class Callbacks {
    public interface ISaveCallback {
        void done(ParseException e);
    }

    public static SaveCallback save(ISaveCallback callback) {
        return new SaveCallback() {
            @Override public void done(ParseException e) {
                callback.done(e);
            }
        };
    }
}