Java8 の新機能を解釈する - ラムダの役割
ラムダが Java にクロージャの概念をもたらすのを長い間待っていましたが、コレクションでラムダを使用しない場合、多くの価値を失います。既存のインターフェイスをラムダ スタイルに移行するという問題は、デフォルトのメソッドによって解決されました。この記事では、Java コレクションのバッチ データ操作を深く分析し、ラムダの最も強力な効果の謎を解明します。
ラムダが Java にクロージャの概念をもたらすのを長い間待っていましたが、コレクションでラムダを使用しなければ、多くの価値が失われます。既存のインターフェイスをラムダ スタイルに移行するという問題は、デフォルトのメソッドによって解決されました。この記事では、Java コレクションのバルク データ操作 (バルク オペレーション) を深く分析し、ラムダの最も強力な役割の謎を解明します。
1. JSR335について
JSRはJava Specific Requestsの略で、Java仕様リクエストを意味します。Java 8バージョンの主な改良点は、Javaを作成することを目的としたLambdaプロジェクト(JSR 335)です。マルチコアの方が簡単 プロセッサがコードを記述します。
2. 外部 VS 内部反復
これまで、Java コレクションは内部反復を表現できず、for または while ループ という外部反復の方法のみを提供していました。
List persons = asList(new Person("Joe"), new Person("Jim"), new Person("John")); for (Person p : persons) { p.setLastName("Doe"); }
上記の例は、いわゆる外部反復である以前のアプローチです。ループは固定シーケンス ループです。今日のマルチコア時代では、ループを並列化したい場合は、上記のコードを変更する必要があります。効率がどの程度向上するかはまだ不確実であり、一定のリスク (スレッドの安全性の問題など) が生じる可能性があります。
内部反復を記述するには、Lambda のようなクラス ライブラリを使用する必要があります。lambda と Collection を使用しましょう。forEach上記のループを書き換えます
persons.forEach(p->p.setLastName("Doe"));
今度は、JDK ライブラリがループを制御します。各人物オブジェクトに姓がどのように設定されるかを気にする必要はありません。ライブラリは、実行環境、並列読み込み、順不同読み込み、または遅延読み込みに応じて、その設定方法を決定できます。これは内部反復であり、クライアントは動作 p.setLastName をデータとして API に渡します。実際、内部反復はコレクションのバッチ操作と密接な関係はありませんが、そのおかげで文法表現の変化を感じることができます。バッチ操作に関連して本当に興味深いのは、新しいストリーム API です。新しい java.util.stream パッケージが JDK 8 に追加されました。
3. ストリーム API
ストリームはデータ ストリームのみを表し、データ構造を持たないため、一度通過した後は通過することはできません (これは、コレクションとは異なり、プログラミング時に注意する必要があります)何度走査されても、データはまだ存在します)、そのソースはコレクション、配列、io などです。
3.1 中間メソッドと終了メソッド
フロー機能は、ビッグデータを操作するためのインターフェースを提供し、データ操作をより簡単かつ高速にします。フィルタリング、マッピング、トラバーサル数の削減などのメソッドがあり、これらのメソッドは中間メソッドと終端メソッドの 2 つのタイプに分けられます。中間メソッドは本質的に連続的なものである必要があります。最終結果を取得したい場合は、エンドポイント操作を使用して、ストリームによって生成された最終結果を収集する必要があります。これら 2 つのメソッドの違いは、戻り値に注目することです。ストリームの場合は中間メソッドであり、そうでない場合は終了メソッドです。
いくつかの中間メソッド (フィルター、マップ) とエンドポイント メソッド (収集、合計) の簡単な紹介
3.1.1フィルター
データ ストリームでのフィルター関数の実装は、最も自然な操作です。まず考えてください。 Stream インターフェイスは、フィルター条件を定義するラムダ式 を使用する操作を表す Predicate 実装を受け入れることができるフィルター メソッドを公開します。
List persons = … Stream personsOver18 = persons.stream().filter(p -> p.getAge() > 18);//过滤18岁以上的人
3.1.2Map
Stream adult= persons .stream() .filter(p -> p.getAge() > 18) .map(new Function() { @Override public Adult apply(Person person) { return new Adult(person);//将大于18岁的人转为成年人 } });
Stream map = persons.stream() .filter(p -> p.getAge() > 18) .map(person -> new Adult(person));
3.1.3Count
int countOfAdult=persons.stream() .filter(p -> p.getAge() > 18) .map(person -> new Adult(person)) .count();
3.1.4Collect
List adultList= persons.stream() .filter(p -> p.getAge() > 18) .map(person -> new Adult(person)) .collect(Collectors.toList());
List adultList = persons .stream() .filter(p -> p.getAge() > 18) .map(person -> new Adult(person)) .collect(Collectors.toCollection(ArrayList::new));
篇幅有限,其他的中间方法和终点方法就不一一介绍了,看了上面几个例子,大家明白这两种方法的区别即可,后面可根据需求来决定使用。
3.2顺序流与并行流
每个Stream都有两种模式:顺序执行和并行执行。
顺序流:
List <Person> people = list.getStream.collect(Collectors.toList());
并行流:
List <Person> people = list.getStream.parallel().collect(Collectors.toList());
顾名思义,当使用顺序方式去遍历时,每个item读完后再读下一个item。而使用并行去遍历时,数组会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。
3.2.1并行流原理:
List originalList = someData; split1 = originalList(0, mid);//将数据分小部分 split2 = originalList(mid,end); new Runnable(split1.process());//小部分执行操作 new Runnable(split2.process()); List revisedList = split1 + split2;//将结果合并
大家对hadoop有稍微了解就知道,里面的 MapReduce 本身就是用于并行处理大数据集的软件框架,其 处理大数据的核心思想就是大而化小,分配到不同机器去运行map,最终通过reduce将所有机器的结果结合起来得到一个最终结果,与MapReduce不同,Stream则是利用多核技术可将大数据通过多核并行处理,而MapReduce则可以分布式的。
3.2.2顺序与并行性能测试对比
如果是多核机器,理论上并行流则会比顺序流快上一倍,下面是测试代码
long t0 = System.nanoTime(); //初始化一个范围100万整数流,求能被2整除的数字,toArray()是终点方法 int a[]=IntStream.range(0, 1_000_000).filter(p -> p % 2==0).toArray(); long t1 = System.nanoTime(); //和上面功能一样,这里是用并行流来计算 int b[]=IntStream.range(0, 1_000_000).parallel().filter(p -> p % 2==0).toArray(); long t2 = System.nanoTime(); //我本机的结果是serial: 0.06s, parallel 0.02s,证明并行流确实比顺序流快 System.out.printf("serial: %.2fs, parallel %.2fs%n", (t1 - t0) * 1e-9, (t2 - t1) * 1e-9);
3.3关于Folk/Join框架
应用硬件的并行性在java 7就有了,那就是 java.util.concurrent 包的新增功能之一是一个 fork-join 风格的并行分解框架,同样也很强大高效,有兴趣的同学去研究,这里不详谈了,相比Stream.parallel()这种方式,我更倾向于后者。
4.总结
如果没有lambda,Stream用起来相当别扭,他会产生大量的匿名内部类,比如上面的3.1.2map例子,如果没有default method,集合框架更改势必会引起大量的改动,所以lambda+default method使得jdk库更加强大,以及灵活,Stream以及集合框架的改进便是最好的证明。
以上がJava8 の新機能を解釈する - ラムダの役割の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









nohup の役割と原理の分析 Unix および Unix 系オペレーティング システムでは、nohup はバックグラウンドでコマンドを実行するためによく使用されるコマンドです。ユーザーが現在のセッションを終了したり、ターミナル ウィンドウを閉じたりしても、コマンドはまだ実行され続けています。この記事では、nohup コマンドの機能と原理を詳しく分析します。 1. nohup の役割: バックグラウンドでのコマンドの実行: nohup コマンドを使用すると、ターミナル セッションを終了するユーザーの影響を受けることなく、長時間実行されるコマンドをバックグラウンドで実行し続けることができます。これは実行する必要があります

Win11システムでファイルのサフィックスを表示するにはどうすればよいですか?詳細説明: Windows 11 オペレーティング システムでは、ファイル拡張子はファイル名の後のドットとその後の文字を指し、ファイルの種類を示すために使用されます。デフォルトでは、Windows 11 システムはファイルのサフィックスを非表示にするため、ファイル エクスプローラーではファイル名のみが表示され、ファイルの種類を直感的に理解することはできません。ただし、一部のユーザーにとっては、ファイルの種類をより適切に識別し、関連する操作を実行するのに役立つため、ファイル接尾辞の表示が必要です。

LinuxDTS の役割と使用法を理解する 組み込み Linux システムの開発において、デバイス ツリー (DeviceTree、略して DTS) は、システム内のハードウェア デバイスとその接続関係と属性を記述するデータ構造です。デバイス ツリーを使用すると、カーネルを変更せずに、Linux カーネルをさまざまなハードウェア プラットフォーム上で柔軟に実行できます。この記事では、LinuxDTS の機能と使用法を紹介し、読者の理解を深めるために具体的なコード例を示します。 1. デバイスツリーの役割 デバイスツリー

PHPにおけるdefine関数の重要性と役割 1.define関数の基本紹介 PHPにおいて、define関数は定数を定義するための重要な関数であり、定数はプログラムの実行中に値が変化しません。定義関数を使用して定義された定数は、スクリプト全体からアクセスでき、グローバルです。 2. 定義関数の構文 定義関数の基本的な構文は次のとおりです。

PHP は、Web 開発で広く使用されているサーバー側スクリプト言語です。その主な機能は、動的な Web コンテンツを生成することです。HTML と組み合わせると、リッチでカラフルな Web ページを作成できます。 PHP は強力で、さまざまなデータベース操作、ファイル操作、フォーム処理、その他のタスクを実行でき、Web サイトに強力な対話性と機能を提供します。次の記事では、詳細なコード例を使用して、PHP の役割と機能をさらに詳しく説明します。まず、PHP の一般的な使用法である動的な Web ページの生成を見てみましょう: P

Golang (Go 言語) には伝統的な意味でのクラスの概念はありませんが、構造体と呼ばれるデータ型が提供され、これによってクラスと同様のオブジェクト指向機能を実現できます。この記事では、構造体を使用してオブジェクト指向機能を実装する方法を説明し、具体的なコード例を示します。構造体の定義と使用法 まず、構造体の定義と使用法を見てみましょう。 Golang では、type キーワードを通じて構造を定義し、必要に応じて使用できます。構造には属性を含めることができます

LinuxBashrc は、Linux システムの構成ファイルであり、ユーザーの Bash (BourneAgainShell) 環境を設定するために使用されます。 Bashrc ファイルには、ユーザーのログインに必要な環境変数や起動スクリプトなどの情報が格納されており、ユーザーのシェル環境をカスタマイズできます。 Linux システムでは、各ユーザーは対応する Bashrc ファイルを持っており、このファイルはユーザーのホーム ディレクトリの隠しフォルダーにあります。 Bashrc ファイルの主な機能は次のとおりです。 環境のセットアップ

CryptoGPTとは何ですか? 3EX の CryptoGPT が通貨サークルへの新たな入り口と言われるのはなぜですか? 7月5日のニュースによると、3EXAI取引プラットフォームは、世界の仮想通貨投資家に包括的でインテリジェントな情報クエリとAI投資アドバイスを提供することを目的とした、AIテクノロジーとビッグデータに基づく革新的なプロジェクトであるCryptoGPTを正式に開始した。 CryptoGPT には、CoinMarketCap の上位 200 コインと数百の高品質なプロジェクト パーティー情報が含まれており、今後も拡大していく予定です。 CryptoGPTを通じて、ユーザーは詳細な取引コンサルティングレポートやAI投資アドバイスを無料で入手でき、情報コンサルティングサービスからインテリジェントな戦略作成、取引の自動実行までのフルスタックのクローズドループを実現します。現在、このサービスは無料です。必要です
