ラムダ式のベストプラクティス

はじめに

Lambda Expression java 8によって導入された関数型プログラミングフレームワーク。前の記事では、ラムダ式の基本的な使用方法についても説明しました。

この記事では、前の記事に基づいた実際のアプリケーションでのラムダ式のベストプラクティス体験について詳しく説明します。

標準の機能インターフェースを使用することをお勧めします

前回の記事で述べたように、javaはjava.util.functionパッケージで多くのFunctionインターフェースを定義しています。基本的に、考えられるすべてのタイプをカバーしています。

次の機能インターフェースをカスタマイズすると、

@FunctionalInterface
public interface Usage {
    String method(String string);
}

次に、テストメソッドでインターフェイスを渡す必要があります。

public String test(String string, Usage usage) {
    return usage.method(string);
}

上で定義した関数インターフェイスは、メソッドmethodを実装し、Stringを受け取ってStringを返す必要があります。したがって、代わりにFunctionを使用できます。

public String test(String string, Function<String, String> fn) {
    return fn.apply(string);
}

標準インターフェースを使用する利点は、ホイールを再発明しないことです。

@FunctionalInterfaceアノテーションを使用する

@FunctionalInterfaceは必須ではありませんが、@ FunctionalInterfaceがなくても機能インターフェイスを定義できます。

ただし、@ FunctionalInterfaceを使用すると、Functional Interfaceの定義に違反したときに警告を発する可能性があります。

大規模なプロジェクトを管理している場合、@ FunctionalInterfaceアノテーションを使用すると、他のユーザーにこのクラスの役割を明確に理解させることができます。

これにより、コードがより標準化され、使いやすくなります。

したがって、次のように定義する必要があります。

@FunctionalInterface
public interface Usage {
    String method(String string);
}

代わりに:

public interface Usage {
    String method(String string);
}

関数型インターフェイスのデフォルトメソッドを乱用しないでください

機能インターフェイスは、実装されていない抽象メソッドを1つだけ持つインターフェイスを指します。

インターフェイスに複数のメソッドがある場合は、defaultキーワードを使用して、そのデフォルトの実装を提供できます。

しかし、インターフェイスは複数を継承でき、クラスは複数のインターフェイスを実装できることはわかっています。同じデフォルトのメソッドが複数のインターフェースで定義されている場合、エラーが報告されます。

一般的に言って、デフォルトのキーワードは通常、コードエラーを回避するためにアップグレードプロジェクトで使用されます。

ラムダ式を使用して機能インターフェイスをインスタンス化する

または上記の例:

@FunctionalInterface
public interface Usage {
    String method(String string);
}

Usageをインスタンス化するには、新しいキーワードを使用できます。

Usage usage = new Usage() {
    @Override
    public String method(String string) {
        return string;
    }
};

しかし、最善の方法はラムダ式を使用することです:

Usage usage = parameter -> parameter;

機能インタフェースのメソッドをパラメータとして書き換えないでください

理解するには?次の2つの方法を確認します。

public class ProcessorImpl implements Processor {
    @Override
    public String process(Callable<String> c) throws Exception {
        // implementation details
    }
 
    @Override
    public String process(Supplier<String> s) {
        // implementation details
    }
}

2つのメソッドのメソッド名は同じですが、渡されるパラメーターのみが異なります。ただし、どちらのパラメーターも機能インターフェースであり、同じラムダ式で表すことができます。

呼び出すとき:

String result = processor.process(() -> "test");

呼び出されたメソッドがわからないため、エラーが発生します。

最善の方法は、2つのメソッドの名前を異なるものに変更することです。

ラムダ式と内部クラスが異なります

前述のとおり、ラムダ式を使用すると内部クラスを置き換えることができます。しかし、2つの範囲は異なります。

内部クラスでは、新しいスコープが作成され、このスコープ内で新しい変数を定義し、これで参照できます。

ただし、Lambda式では新しいスコープが定義されていないため、これをLambda式で使用すると、外部クラスを参照します。

例を見てみましょう:

private String value = "Outer scope value";

public String scopeExperiment() {
    Usage usage = new Usage() {
        String value = "Inner class value";
 
        @Override
        public String method(String string) {
            return this.value;
        }
    };
    String result = usage.method("");
 
    Usage usageLambda = parameter -> {
        String value = "Lambda value";
        return this.value;
    };
    String resultLambda = usageLambda.method("");
 
    return "Results: result = " + result + 
      ", resultLambda = " + resultLambda;
}

上記の例では、「Results:result = Inner class value、resultLambda = Outer scope value」が出力されます

ラムダ式はできるだけ簡潔です

一般的に言えば、1行のコードで十分です。ロジックがたくさんある場合は、ロジックをメソッドにカプセル化して、ラムダ式でメソッドを呼び出すことができます。

ラムダ式は最終的に式であるため、式が短いほど優れています。

Javaは型推論を使用して受信パラメーターの型を判別するため、次のように、ラムダ式のパラメーターでパラメーター型を渡さないようにします。

(a, b) -> a.toLowerCase() + b.toLowerCase();

代わりに:

(String a, String b) -> a.toLowerCase() + b.toLowerCase();

パラメータが1つしかない場合は、括弧は不要です。

a -> a.toLowerCase();

代わりに:

(a) -> a.toLowerCase();

戻り値は戻り値をもたらす必要はありません:

a -> a.toLowerCase();

代わりに:

a -> {return a.toLowerCase()};

使い方

ラムダ式をより簡潔にするために、メソッド参照を使用できる場合はメソッド参照を使用できます。

a -> a.toLowerCase();

と置き換えることができます:

String::toLowerCase;

実質的に最終的な変数

final以外の変数がラムダ式で参照されている場合、エラーが報告されます。

finalとはどういう意味ですか?これはおおよその最終的な意味です。変数が1回だけ割り当てられている限り、コンパイラーはその変数を事実上最終的なものとして扱います。

    String localVariable = "Local";
    Usage usage = parameter -> {
         localVariable = parameter;
        return localVariable;
    };

上記の例では、localVariableが2回割り当てられているため、Effectiveally Final変数ではなく、コンパイルしてエラーを報告します。

なぜこのように設定する必要があるのですか?ラムダ式は通常、並列計算で使用されるため、複数のスレッドが同時に変数にアクセスする場合、効果的にFinal変数は予期しない変更を防ぐことができます。

おわりに

ラムダは非常に便利な機能です。私の友人が仕事でそれを習得できることを願っています。

私の公開番号に注意を払うことを歓迎します:プログラムのそれらのこと、あなたをもっとエキサイティングに待っています!
詳細については、www.flydean.comをご覧ください

元の記事を168件公開 177 件を賞賛 47万回の閲覧

おすすめ

転載: blog.csdn.net/superfjj/article/details/105649643