ホームページ Java &#&チュートリアル Java 8の新機能、ラムダ式の使い方(使用例)

Java 8の新機能、ラムダ式の使い方(使用例)

Jan 23, 2017 pm 03:12 PM

ラムダが Java にクロージャの概念をもたらすのを長い間待っていましたが、コレクションでラムダを使用しない場合、多くの価値を失います。既存のインターフェイスをラムダ スタイルに移行するという問題は、デフォルトのメソッドによって解決されました。この記事では、Java コレクションのバルク データ操作 (バルク オペレーション) を深く分析し、ラムダの最も強力な役割の謎を解明します。

1. JSR335 について

JSR は Java Specific Requests の略で、Java のコードを書きやすくすることを目的とした Java 8 バージョンの主な改良点です。マルチコアプロセッサ。 JSR 335=ラムダ式 + インターフェイスの改善 (デフォルトのメソッド) + バッチ データ操作。前の 2 つの記事と合わせて、JSR335 の関連内容を完全に学習しました。

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 ライブラリがループを制御するので、最後のループを気にする必要はありません。 name.name が各人物オブジェクトに設定されると、ライブラリは実行環境、並列読み込み、順不同読み込み、または遅延読み込みに応じてその方法を決定できます。これは内部反復であり、クライアントは動作 p.setLastName をデータとして API に渡します。

内部反復は、実際にはコレクションのバッチ操作とは密接に関係していませんが、文法表現の変化を感じることができます。バッチ操作に関連して本当に興味深いのは、新しいストリーム API です。新しい java.util.stream パッケージが JDK 8 に追加されました。


3. ストリーム API

ストリームはデータ ストリームを表すだけであり、データ構造を持たないため、一度走査した後は再度走査することはできません (コレクションとは異なり、プログラミング時にこれに注意する必要があります)何度走査されてもデータはまだ存在します)、そのソースはコレクション、配列、io などです。

3.1 中間メソッドとエンドポイントメソッド

フローの機能は、ビッグデータを操作するためのインターフェイスを提供し、データ操作をより簡単かつ高速にすることです。フィルタリング、マッピング、トラバーサル数の削減などのメソッドがあり、これらのメソッドは中間メソッドと終端メソッドの 2 つのタイプに分けられます。中間メソッドは本質的に連続的なものである必要があります。最終結果を取得したい場合は、エンドポイント操作を使用して、ストリームによって生成された最終結果を収集する必要があります。これら 2 つのメソッドの違いは、戻り値に注目することです。ストリームの場合は中間メソッドであり、そうでない場合は終了メソッドです。詳細については、Stream の API を参照してください。

いくつかの中間メソッド (フィルター、マップ) とエンドポイント メソッド (収集、合計) の簡単な紹介

3.1.1フィルター

データ ストリームにフィルター関数を実装することは、最初に考えることができる最も自然な操作です。 Stream インターフェイスは、フィルター条件を定義するラムダ式を使用する操作を表す Predicate 実装を受け入れるフィルター メソッドを公開します。

List persons = …
Stream personsOver18 = persons.stream().filter(p -> p.getAge() > 18);//过滤18岁以上的人
ログイン後にコピー

3.1.2Map

オブジェクトの変換時などに、いくつかのデータをフィルタリングするとします。 Map オペレーションを使用すると、入力パラメータを受け入れて返す Function 実装 (Function の一般的な T と R はそれぞれ実行入力と実行結果を表します) を実行できます。まず、匿名内部クラスの形式でそれを記述する方法を見てみましょう:

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

count メソッドはストリーム メソッドのエンドポイントです。 、フロー結果の最終統計を作成し、int を返すことができます。たとえば、18 歳以上の人の合計数を計算してみましょう:

int countOfAdult=persons.stream()
                       .filter(p -> p.getAge() > 18)
                       .map(person -> new Adult(person))
                       .count();
ログイン後にコピー

3.1.4Collect

collect メソッドもエンドポイントです。最終結果を収集できるフローのメソッド

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));
ログイン後にコピー

スペースが限られており、他の中間メソッドとエンドポイントメソッドは導入されません上記の例を 1 つずつ読んだ後、これら 2 つの方法の違いを理解でき、後で必要に応じて使用できます。

3.2 順次ストリームと並列ストリーム

各ストリームには、順次実行と並列実行の 2 つのモードがあります。
逐次フロー:

List <Person> people = list.getStream.collect(Collectors.toList());
ログイン後にコピー

並列フロー:

List <Person> people = list.getStream.parallel().collect(Collectors.toList());
ログイン後にコピー

その名前が示すように、逐次メソッドを使用してトラバースする場合は、次の項目を読み取る前に各項目を読み取ります。並列トラバーサルを使用する場合、配列は複数のセグメントに分割され、それぞれが異なるスレッドで処理され、結果がまとめて出力されます。

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;//将结果合并
ログイン後にコピー

3.2.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 パッケージの新機能の 1 つは、非常に強力で効率的なもので、興味のある学生はそれを学ぶことができます。ここでは詳細には触れませんが、Stream.Parallel() と比較すると、後者の方が好きです。

4. 概要

ラムダがない場合、Stream は、上記の 3.1.2map の例のように、大量の匿名内部クラスを生成します。コレクション フレームワークでは必然的に多くの変更が発生するため、Lambda+default メソッドにより JDK ライブラリがより強力かつ柔軟になるのは、ストリームとコレクション フレームワークの改善が何よりの証拠です。

Java8 ラムダ式の新機能 (使用例) に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? 会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? Apr 19, 2025 pm 04:51 PM

一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? Apr 19, 2025 pm 11:42 PM

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? Apr 19, 2025 pm 06:21 PM

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Apr 19, 2025 pm 11:45 PM

intellijideaultimatiateバージョンを使用してスプリングを開始します...

名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? 名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? Apr 19, 2025 pm 11:30 PM

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

Javaオブジェクトを配列に安全に変換する方法は? Javaオブジェクトを配列に安全に変換する方法は? Apr 19, 2025 pm 11:33 PM

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Apr 19, 2025 pm 11:36 PM

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

名前を数字に変換してグループ内でソートを実装する方法は? 名前を数字に変換してグループ内でソートを実装する方法は? Apr 19, 2025 pm 01:57 PM

名前を数字に変換してグループ内でソートを実装する方法は?ユーザーをグループでソートする場合、ユーザーの名前を数字に変換して、異なる可能性があることがよくあります...

See all articles