要約: ラムダ式は、Java 8 によってもたらされたいくつかの重要な新機能の 1 つです。ラムダ式を借用すると、Java プログラムの設計をより簡潔にすることができます。この記事は Java 8 の最初の新機能であり、動作のパラメーター化、ラムダ式、メソッド参照について説明します。
ラムダ式は、java8 によってもたらされたいくつかの重要な新機能の 1 つです。ラムダ式を借用すると、Java プログラムの設計をより簡潔にすることができます。最近、新しいプロジェクトはバージョン 1.6 を放棄し、完全に Java8 に基づいて開発されています。この記事は Java8 の新機能に関する最初の記事であり、動作のパラメーター化、ラムダ式、メソッド参照について説明します。
1. 動作のパラメータ化
簡単に言うと、関数の本体にはテンプレート クラスの一般的なコードのみが含まれており、ビジネス シナリオに応じて変更される一部のロジックはパラメーターの形式で関数に渡されます。動作パラメータ化により、プログラムの汎用性が高まり、頻繁な変更に対応できるようになります。
プログラムを通じてリンゴをフィルタリングする必要があるとします。最初にリンゴのエンティティを定義します:
/** * 苹果实体 * * @author zhenchao.wang 2016-09-17 12:49 * @version 1.0.0 */ public class Apple { /** 编号 */ private long id; /** 颜色 */ private Color color; /** 重量 */ private float weight; /** 产地 */ private String origin; public Apple() { } public Apple(long id, Color color, float weight, String origin) { this.id = id; this.color = color; this.weight = weight; this.origin = origin; } // 省略getter和setter }
ユーザーの最初の要求は単にプログラムを通じて緑色のリンゴをフィルタリングすることであるため、すぐに実装できます。プログラムを通じてそれを実行します:
/** * 筛选绿苹果 * * @param apples * @return */ public static List<Apple> filterGreenApples(List<Apple> apples) { List<Apple> filterApples = new ArrayList<>(); for (final Apple apple : apples) { if (Color.GREEN.equals(apple.getColor())) { filterApples.add(apple); } } return filterApples; }
しばらくして、ユーザーが新しい要件を提示し、プログラムを通じて赤いリンゴをフィルタリングできるようにしたい場合は、赤いリンゴをフィルタリングする機能を追加しました:
/** * 筛选红苹果 * * @param apples * @return */ public static List<Apple> filterRedApples(List<Apple> apples) { List<Apple> filterApples = new ArrayList<>(); for (final Apple apple : apples) { if (Color.RED.equals(apple.getColor())) { filterApples.add(apple); } } return filterApples; }
より良い実装は、色をパラメータとして関数に渡すことです。そうすれば、将来ユーザーからのさまざまなカラー フィルター要求に対応できるようになります。
/** * 自定义筛选颜色 * * @param apples * @param color * @return */ public static List<Apple> filterApplesByColor(List<Apple> apples, Color color) { List<Apple> filterApples = new ArrayList<>(); for (final Apple apple : apples) { if (color.equals(apple.getColor())) { filterApples.add(apple); } } return filterApples; }
このように設計した後は、もう心配する必要はありません。ユーザー カラー スクリーニング要件が変更されましたが、残念なことに、ある日、ユーザーが、重量が特定の標準に達するリンゴを選択できるようにするという要件を提起しました。前のレッスンでは、重量標準もパラメータとしてスクリーニング関数に渡しました。それで取得:
/** * 筛选指定颜色,且重要符合要求 * * @param apples * @param color * @param weight * @return */ public static List<Apple> filterApplesByColorAndWeight(List<Apple> apples, Color color, float weight) { List<Apple> filterApples = new ArrayList<>(); for (final Apple apple : apples) { if (color.equals(apple.getColor()) && apple.getWeight() >= weight) { filterApples.add(apple); } } return filterApples; }
これは本当にパラメーターを渡す良い方法ですか?フィルタリング条件がますます多くなり、組み合わせモードがますます複雑になる場合、すべての状況を考慮し、それぞれの状況に対応する戦略を用意する必要がありますか? また、これらの関数はフィルタリング条件の一部が異なるだけで、残りは異なります。同じテンプレート コード (コレクションをトラバース) を使用する場合、この時点で動作をパラメーター化できます 。これにより、関数はテンプレート コードのみを保持し、フィルター条件を抽出してパラメーターとして渡します。java8 より前では、これは次のように実現されていました。フィルターインターフェイスの定義:
/** * 苹果过滤接口 * * @author zhenchao.wang 2016-09-17 14:21 * @version 1.0.0 */ @FunctionalInterface public interface AppleFilter { /** * 筛选条件抽象 * * @param apple * @return */ boolean accept(Apple apple); } /** * 将筛选条件封装成接口 * * @param apples * @param filter * @return */ public static List<Apple> filterApplesByAppleFilter(List<Apple> apples, AppleFilter filter) { List<Apple> filterApples = new ArrayList<>(); for (final Apple apple : apples) { if (filter.accept(apple)) { filterApples.add(apple); } } return filterApples; }上記の動作を抽象化した後、特定の呼び出し場所でフィルター条件を設定し、その条件をパラメータとしてメソッドに渡すことができます:
public static void main(String[] args) { List<Apple> apples = new ArrayList<>(); // 筛选苹果 List<Apple> filterApples = filterApplesByAppleFilter(apples, new AppleFilter() { @Override public boolean accept(Apple apple) { // 筛选重量大于100g的红苹果 return Color.RED.equals(apple.getColor()) && apple.getWeight() > 100; } }); }上記の動作 パラメータ化メソッドは次を使用して実装されます。この設計は、
java.util.Comparator、
java.util.concurrent.Callableなどの jdk 内でもよく使用されます。このタイプのインターフェイスを使用する場合、特定の呼び出し場所で匿名クラスを使用して、特定の実行ロジックを指定できます。この関数は、上記のコード ブロックから判断すると、非常にマニアックではありますが、十分に簡潔ではありません。Java8 では、ラムダ式を使用して簡素化できます。
// 筛选苹果 List<Apple> filterApples = filterApplesByAppleFilter(apples, (Apple apple) -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100);ラムダ式を使用して大幅に簡素化されています。 java のラムダ式~
2. ラムダ式の定義
まずラムダ式を明確にする必要がありますが、式は本質的には関数に属しません。特定のクラスには、パラメータ リスト、関数本体、戻り値の型があり、例外をスローする機能があります。第二に、ラムダ式には特定の関数名がありません。ラムダ式はパラメータのように渡すことができます。コードの記述が大幅に簡素化されます。形式は次のように定義されます:
形式 1: パラメータ リスト-> 式 形式 2: パラメータ リスト-> {式セット} ラムダ式は return キーワードを意味するので、単一の In式の場合、明示的に return キーワードを記述する必要はありませんが、式がステートメントのコレクションである場合は、明示的に return を追加し、複数の式を中括弧
{ }
で囲む必要があります。例をいくつか見てみましょう。
//返回给定字符串的长度,隐含return语句 (String s) -> s.length() // 始终返回42的无参方法 () -> 42 // 包含多行表达式,则用花括号括起来 (int x, int y) -> { int z = x * y; return x + z; }3. 関数型インターフェースに依存してラムダ式を使用する
ラムダ式の使用には関数型インターフェースの助けが必要です。つまり、関数型インターフェースが出現した場合にのみ、ラムダ式を使用して式を表現できます。式が簡素化されます。
関数型インターフェースは、
1 つの抽象メソッド
/** * 苹果过滤接口 * * @author zhenchao.wang 2016-09-17 14:21 * @version 1.0.0 */ @FunctionalInterface public interface AppleFilter { /** * 筛选条件抽象 * * @param apple * @return */ boolean accept(Apple apple); }
AppleFilterには 1 つの抽象メソッド
accept(Apple apple)
のみが含まれており、インターフェースを定義する際には、これを関数インターフェースとみなします。追加されました
@FunctionalInterface
注解,用于标记该接口是函数式接口,不过这个接口是可选的,当添加了该接口之后,编译器就限制了该接口只允许有一个抽象方法,否则报错,所以推荐为函数式接口添加该注解。
jdk自带的函数式接口
jdk为lambda表达式已经内置了丰富的函数式接口,如下表所示(仅列出部分):
函数式接口 | 函数描述符 | 原始类型特化 |
---|---|---|
Predicate |
T -> boolean | IntPredicate, LongPredicate, DoublePredicate |
Consumer |
T -> void | IntConsumer, LongConsumer, DoubleConsumer |
Funcation |
T -> R | IntFuncation |
Supplier |
() -> T | BooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier |
UnaryOperator |
T -> T | IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator |
BinaryOperator |
(T, T) -> T | IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator |
BiPredicate |
(L, R) -> boolean | |
BiConsumer |
(T, U) -> void | |
BiFunction |
(T, U) -> R |
下面分别就
Predicate<T>
、
Consumer<T>
、
Function<T, R>
的使用示例说明。
Predicate
@FunctionalInterface public interface Predicate<T> { /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); }
Predicate的功能类似于上面的
AppleFilter
,利用我们在外部设定的条件对于传入的参数进行校验,并返回验证结果
boolean
,下面利用
Predicate
对List集合的元素进行过滤:
/** * 按照指定的条件对集合元素进行过滤 * * @param list * @param predicate * @param* @return */ public List filter(List list, Predicate<T> predicate) { List newList = new ArrayList (); for (final T t : list) { if (predicate.test(t)) { newList.add(t); } } return newList; }
利用上面的函数式接口过滤字符串集合中的空字符串:
demo.filter(list, (String str) -> null != str && !str.isEmpty()); Consumer<T> @FunctionalInterface public interface Consumer<T> { /** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); }
Consumer提供了一个accept抽象函数,该函数接收参数,但不返回值,下面利用
Consumer
遍历集合:
/** * 遍历集合,执行自定义行为 * * @param list * @param consumer * @param*/ public void filter(List list, Consumer<T> consumer) { for (final T t : list) { consumer.accept(t); } }
利用上面的函数式接口,遍历字符串集合,并打印非空字符串:
demo.filter(list, (String str) -> { if (StringUtils.isNotBlank(str)) { System.out.println(str); } });
Function
@FunctionalInterface public interface Function<T, R> { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ R apply(T t); }
Funcation执行转换操作,输入是类型T的数据,返回R类型的数据,下面利用
Function
对集合进行转换:
/** * 遍历集合,执行自定义转换操作 * * @param list * @param function * @param* @param * @return */ public List filter(List list, Function<T, R> function) { List newList = new ArrayList (); for (final T t : list) { newList.add(function.apply(t)); } return newList; }
下面利用上面的函数式接口,将一个封装字符串(整型数字的字符串表示)的接口,转换成整型集合:
demo.filter(list, (String str) -> Integer.parseInt(str));
上面这些函数式接口还提供了一些逻辑操作的默认实现,留到后面介绍java8接口的默认方法时再讲吧~
使用过程中需要注意的一些事情
类型推断
在编码过程中,有时候可能会疑惑我们的调用代码会去具体匹配哪个函数式接口,实际上编译器会根据参数、返回类型、异常类型(如果存在)等做正确的判定。
在具体调用时,在一些时候可以省略参数的类型,从而进一步简化代码:
/
/ 筛选苹果 List<Apple> filterApples = filterApplesByAppleFilter(apples, (Apple apple) -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100); // 某些情况下我们甚至可以省略参数类型,编译器会根据上下文正确判断 List<Apple> filterApples = filterApplesByAppleFilter(apples, apple -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100);
局部变量
上面所有例子我们的lambda表达式都是使用其主体参数,我们也可以在lambda中使用局部变量,如下:
int weight = 100; List<Apple> filterApples = filterApplesByAppleFilter(apples, apple -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= weight);
该例子中我们在lambda中使用了局部变量weight,不过在lambda中使用局部变量必须要求该变量 显式声明为final或事实上的final ,这主要是因为局部变量存储在栈上,lambda表达式则在另一个线程中运行,当该线程视图访问该局部变量的时候,该变量存在被更改或回收的可能性,所以用final修饰之后就不会存在线程安全的问题。
四. 方法引用
采用方法引用可以更近一步的简化代码,有时候这种简化让代码看上去更加的直观,先看一个例子:
/* ... 省略apples的初始化操作 */ // 采用lambda表达式 apples.sort((Apple a, Apple b) -> Float.compare(a.getWeight(), b.getWeight())); // 采用方法引用 apples.sort(Comparator.comparing(Apple::getWeight));
方法引用通过
::
将方法隶属和方法自身连接起来,主要分为三类:
静态方法
(args) -> ClassName.staticMethod(args)
转换成
ClassName::staticMethod
参数的实例方法
(args) -> args.instanceMethod()
转换成
ClassName::instanceMethod // ClassName是args的类型
外部的实例方法
(args) -> ext.instanceMethod(args)
转换成
ext::instanceMethod(args)
以上就是Java8 新特性之 Lambda 表达式 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

jvm'sperformanceiscompetitivewitherruntimes、sped、safety、andproductivityの提供

javaachievesplatformedentenceTheThejavavirtualMachine(JVM)、avainwithcodetorunonanyplatformwithajvm.1)codescompiledintobytecode、notmachine-specificcode.2)

thejvmisanabstractcomputingMachineCrucialForrunningJavaProgramsDuetoitsPlatForm-IndopentInterChitecture.Itincludes:1)ClassLoaderForloadingClasses、2)Runtimedataareaforforforatastorage、3)executionEngineWithinterter、Jitcompiler、およびGarbagecolfecolfecolfececolfecolfer

jvmhasacloserelationshiptheosasittrantesjavabytecodecodecodecodecodecodecodecodecodecodecodecodecodetructions、manageSmemory、およびhandlesgarbagecollection.thisrelationshipallowsjavatorunonvariousosenvirnments、Butalsedentsはspeedifediferentjvmbeviorhiorsandosendisfredediferentjvmbehbehioorysando

Javaの実装「Write and、Run Everywherewhere」はBytecodeにコンパイルされ、Java仮想マシン(JVM)で実行されます。 1)Javaコードを書き、それをByteCodeにコンパイルします。 2)JVMがインストールされたプラットフォームでByteCodeが実行されます。 3)Javaネイティブインターフェイス(JNI)を使用して、プラットフォーム固有の機能を処理します。 JVMの一貫性やプラットフォーム固有のライブラリの使用などの課題にもかかわらず、Woraは開発効率と展開の柔軟性を大幅に向上させます。

javaachievesplatformentenceTheTheTheJavavirtualMachine(JVM)、CodetorunondifferentoperatingSystemswithOutModification.thejvmcompilesjavacodeplatform-IndopentedbyTecodeを承認することを許可します

javaispowerfulfulduetoitsplatformindepentence、object-orientednature、richstandardlibrary、performancecapability、andstrongsecurityfeatures.1)platformendependenceallowseplicationStorunonaydevicesupportingjava.2)オブジェクト指向のプログラマン型

上位のJava関数には、次のものが含まれます。1)オブジェクト指向プログラミング、サポートポリ型、コードの柔軟性と保守性の向上。 2)例外処理メカニズム、トライキャッチ式ブロックによるコードの堅牢性の向上。 3)ゴミ収集、メモリ管理の簡素化。 4)ジェネリック、タイプの安全性の向上。 5)コードをより簡潔で表現力豊かにするためのAMBDAの表現と機能的なプログラミング。 6)最適化されたデータ構造とアルゴリズムを提供するリッチ標準ライブラリ。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

Dreamweaver Mac版
ビジュアル Web 開発ツール

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません
