Java でラムダ式を使用するにはどうすればよいですか?

王林
リリース: 2023-04-21 20:31:14
転載
1028 人が閲覧しました

ラムダ式の概要

  • #ラムダ式の本質は単なる「構文糖衣」であり、コンパイラーによって推論され、変換や変換を支援します。これを通常のコードにラップすると、より少ないコードで同じ機能を実現できます。

  • ラムダ式は、Java SE 8 の重要な新機能です。

Lambda と匿名内部クラス

Lamda 式は、SAM (SingleAbstractMethod、抽象メソッドを含むインターフェイス) 環境のアプリケーションを指します。簡略化された形式です。定義の。

匿名内部クラスに対する Lambda の利点

簡潔性 (詳細については、以下の「関数インターフェイス」を参照)

匿名内部クラスに対する Lambda の利点クラスのデメリット

  • #Lamdaに対応するインターフェースはメソッドを1つしか持つことができません。

  • #匿名内部クラスに対応するインターフェイスには複数のメソッドを持つことができます

#インターフェイスの要件

1.Lambda では、インターフェイスに実装する必要があるメソッドは 1 つだけ (つまり、抽象メソッド) であると規定されています。

インターフェイスには、1 つの抽象メソッド (1 つだけ存在可能)、複数のデフォルト メソッド、および複数の静的メソッドが同時に存在できます。

// jdk 8 には別の新機能があります: デフォルト デフォルトで変更されたメソッドにはデフォルトの実装があり、実装する必要があるメソッドではないため、ラムダ式の使用には影響しません。

2.@FunctionalInterface: 関数インターフェイスを変更するために使用されます。

@FunctionalInterface は記述してもしなくても構いません。このアノテーションは主にコンパイル レベルのエラー チェックに使用されます。インターフェイスが関数インターフェイス定義に準拠していない場合、コンパイラはエラーを報告します。

正しい例、エラーは報告されません:

@FunctionalInterface
public interface HelloWorldService {
    void sayHello(String msg);
}
ログイン後にコピー

間違った例、エラーは報告されます:

インターフェイスには、関数インターフェイスの定義に違反する 2 つの抽象メソッドが含まれており、インターフェース オーバーライドされていない抽象メソッドが複数見つかりました。

Java でラムダ式を使用するにはどうすればよいですか?注: @FunctionalInterface を追加しても追加しなくても、インターフェイスが関数型インターフェイスであるかどうかには影響しません。このアノテーションは、インターフェイスに抽象が 1 つだけ含まれているかどうかを確認するようコンパイラーに通知するだけです。方法。

変数とスコープ

    ラムダ式は、final とマークされた外部ローカル変数のみを参照できます。つまり、スコープ外で定義されたローカル変数はラムダ内で変更できません。変更しないとコンパイル エラーが報告されます。
  • #ラムダ式のローカル変数は、final として宣言する必要はありません。ただし、後続のコードによって変更してはなりません (つまり、最終セマンティクスで暗黙的に)
  • ラムダ式では、ローカル変数と同じ名前のパラメーターまたはローカル変数を宣言することはできません。
  • #形式

  • ラムダ式の重要な機能

オプションの型宣言: パラメーターの型を宣言する必要はありません。コンパイラーのパラメーター値を均一に識別できます。

  • オプションのパラメータのかっこ: 1 つのパラメータをかっこで定義する必要はありませんが、複数のパラメータをかっこで定義する必要があります。

  • オプションの中括弧: 本文にステートメントが含まれる場合、中括弧は必要ありません。例: () -> Sysout.out.println("Test");

  • オプションの戻りキーワード: 本体に式の戻り値が 1 つしかない場合、コンパイラは自動的に値を返します。 、式が値を返すことを示すには、中括弧を指定する必要があります。

  • ラムダ式の簡単な例

  • 1. パラメーターは必要ありません、戻り値は 5

() -> 5

です。

2. 1 つのパラメータ (数値型) を受け取り、その値の 2 倍を返す

x -> 2 * x

3. 2 つのパラメータ (数値型) を受け取り、それらを返す 違い

(x, y) -> x – y

4. 2 つの int 型整数を受け取り、その合計を返します

(int x, int y) -> ; ; System.out.print(s)

構文形式

形式:

(パラメータ) - > ステートメント または (パラメーター) ->{ ステートメント; }

左側: Lambda 式のパラメーター リスト右側: 実行する必要がある関数ラムダ式 (ラムダ本体)

構文形式 1: パラメータなし、戻り値なし

#() -> Sysout.out.println(" Test") ;

構文形式 2: パラメーターは 1 つあり、戻り値はありません

(X)-> Sysout.out。 println(x );

文法形式 3: パラメータ括弧がある場合は記述する必要はありません

##X-> ; Sysout.out.println(x) ;

文法形式 4: Lambda 本体には 3 つ以上のパラメータと戻り値があり、複数のステートメントがあります。{} は構文本体で使用する必要があります。

    Comparator<Integer> comparator = (o1, o2) -> {
        System.out.println("Test");
        return Integer.compare(o1, o2);
    };
ログイン後にコピー

#文法形式 5: Lambda 本体で使用するステートメントは 1 つだけです。return と {} は省略できます

コンパレータ コンパレータ = (o1, o2)-> Integer.compare(o1, o2);

语法格式六:表达式的参数列表的数据类型可以省略不写,JVM编译器通过上下文推断出数据类型

(x ,y ) ->Integer.compare(x ,y)

实例

无参数无返回值

package org.example.a;
 
@FunctionalInterface
interface Interface {
    void run();
}
 
public class Demo{
    public static void main(String[] args) {
        Interface params = new Interface() {
            @Override
            public void run() {
                System.out.println("Anonymous Internal Class: ");
            }
        };
 
        Interface params1 = () -> System.out.println("Lambda: ");
 
        params.run();
        params1.run();
    }
}
ログイン後にコピー

执行结果

Anonymous Internal Class:
Lambda:

有参数无返回值

package org.example.a;
 
@FunctionalInterface
interface Interface {
    void run(String s);
}
 
public class Demo{
    public static void main(String[] args) {
        Interface params = new Interface() {
            @Override
            public void run(String s) {
                System.out.println("Anonymous Internal Class: " + s);
            }
        };
 
        Interface params1 = (s) -> System.out.println("Lambda: " + s);
 
        params.run("hello");
        params1.run("hi");
    }
}
ログイン後にコピー

执行结果

Anonymous Internal Class: hello
Lambda: hi

有参数有返回值

package org.example.a;
 
@FunctionalInterface
interface Interface {
    String run(String s);
}
 
public class Demo{
    public static void main(String[] args) {
        Interface params = new Interface() {
            @Override
            public String run(String s) {
                System.out.println("Anonymous Internal Class: " + s);
                return "abc";
            }
        };
 
        Interface params1 = (s) -> {
            System.out.println("Lambda: " + s);
            return "def";
        };
 
        System.out.println(params.run("hello"));
        System.out.println(params1.run("hi"));
    }
}
ログイン後にコピー

执行结果

Anonymous Internal Class: hello
abc
Lambda: hi
def

lambda作为参数

传递一个函数

package org.example.a;
 
interface IRun {
    String welcome(String string);
}
 
class Util {
    public static long executionTime1(IRun iRun, String string) {
        long startTime = System.currentTimeMillis();
        System.out.println(iRun.welcome(string));
        //本处刻意添加这一无意义延时,防止执行太快返回0
        try {
            Thread.sleep(10);
        } catch (Exception e) {
            System.out.println(e);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }
 
    public long executionTime2(IRun iRun, String string) {
        long startTime = System.currentTimeMillis();
        System.out.println(iRun.welcome(string));
        //本处刻意添加这一无意义延时,防止执行太快返回0
        try {
            Thread.sleep(10);
        } catch (Exception e) {
            System.out.println(e);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }
 
    public static String hello(String string){
        String tmp;
        tmp = "hello: " + string;
        return tmp;
    }
 
    public String hi(String string){
        String tmp;
        tmp = "hi: " + string;
        return tmp;
    }
}
 
public class Demo {
    public static void main(String[] args) {
        long time1 = Util.executionTime1(Util::hello, "Tony");
        long time2 = new Util().executionTime2(new Util()::hi, "Pepper");
        System.out.println("time1: " + time1 + "ms");
        System.out.println("time2: " + time2 + "ms");
    }
}
ログイン後にコピー

执行结果

hello: Tony
hi: Pepper
time1: 11ms
time2: 11ms

直接传递lambda函数

package org.example.a;
 
interface IRun {
    String welcome(String string);
}
 
class Util {
    public static long executionTime(IRun iRun, String string) {
        long startTime = System.currentTimeMillis();
        System.out.println(iRun.welcome(string));
        //本处刻意添加这一无意义延时,防止执行太快返回0
        try {
            Thread.sleep(10);
        } catch (Exception e) {
            System.out.println(e);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }
}
 
public class Demo {
    public static void main(String[] args) {
        long time = Util.executionTime((string -> {
                    String tmp;
                    tmp = "hello: " + string;
                    return tmp;
                })
                , "Tony");
        System.out.println("time: " + time + "ms");
    }
}
ログイン後にコピー

执行结果

hello: Tony
time: 11ms

遍历集合

package org.example.a;
 
import java.util.ArrayList;
import java.util.List;
 
public class Demo{
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
 
        //以前的循环方式
        for (String string : list) {
            System.out.println(string);
        }
 
        //使用lambda表达式输出list中的每个值
        list.forEach(c->{
            System.out.println(c);
        });
 
        // 在 Java 8 中使用双冒号操作符(double colon operator)。也属于lamda表达式
        list.forEach(System.out::println);
    }
}
ログイン後にコピー

执行结果

aaa
bbb
aaa
bbb
aaa
bbb

创建线程

package org.example.a;
 
public class Demo{
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Anonymous Internal Class !");
            }
        }).start();
 
        new Thread(() -> System.out.println("Lambda !")).start();
    }
}
ログイン後にコピー

执行结果

Anonymous Internal Class !
Lambda !

排序

package org.example.a;
 
import java.util.Arrays;
import java.util.Comparator;
 
public class Demo{
    public static void main(String[] args) {
        String[] players = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka"};
        
        Arrays.sort(players, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return (o1.compareTo(o2));
            }
        });
 
//        Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
//        Arrays.sort(players, sortByName);
        
//        Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
        
        for(String string:players){
            System.out.println(string);
        }
    }
}
ログイン後にコピー

执行结果(换成注释掉的两种任意一种都是一样的)

Novak Djokovic
Rafael Nadal
Stanislas Wawrinka

以上がJava でラムダ式を使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!