map()とflatMap()の違い

map()とflatMap()の違い

1. 概要

map()およびflatMap() APIは、関数型言語に由来します。 Java 8では、それらはOptional, StreamCompletableFuture (althoughでわずかに異なる名前で見つけることができます)。

Streamsはオブジェクトのシーケンスを表しますが、オプションは存在または不在の値を表すクラスです。 他の集計操作の中には、map()メソッドとflatMap()メソッドがあります。

両方が同じ戻り値の型,を持っているという事実にもかかわらず、それらはかなり異なります。 ストリームとオプションの例をいくつか分析して、これらの違いを説明しましょう。

参考文献:

Javaでマップを反復処理する

JavaのMapのエントリを反復処理するさまざまな方法を学びます。

Jacksonでのシリアル化とシリアル化解除のマッピング

ジャクソンを使用してJavaマップをシリアル化および逆シリアル化するための迅速かつ実用的なガイド。

Javaのマップに重複キーを保存する方法は?

Javaでマルチマップを使用して重複キーを処理するための迅速かつ実用的なガイド。

2. オプションのマップとフラットマップ

map()メソッドはOptionalでうまく機能します–関数が必要な正確な型を返す場合:

Optional s = Optional.of("test");
assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));

ただし、より複雑なケースでは、Optionalも返す関数が与えられる場合があります。 このような場合、map()の実装は内部で追加のラッピングを行うため、map()を使用するとネストされた構造になります。

この状況をよりよく理解するために、別の例を見てみましょう。

assertEquals(Optional.of(Optional.of("STRING")),
  Optional
  .of("string")
  .map(s -> Optional.of("STRING")));

ご覧のとおり、最終的にネストされた構造体Optional<Optional<String>>.になります。これは機能しますが、使用するのがかなり面倒で、追加のnullセーフ性がないため、フラットな構造体を維持することをお勧めします。

それがまさにflatMap()が私たちに役立つことです。

assertEquals(Optional.of("STRING"), Optional
  .of("string")
  .flatMap(s -> Optional.of("STRING")));

3. ストリームのマップとフラットマップ

どちらの方法もOptionalに対して同様に機能します。

map()メソッドは、基になるシーケンスをStreamインスタンスでラップしますが、flatMap()メソッドでは、ネストされたStream<Stream<R>>構造を回避できます。

次の例では、map()は、入力Stream:の要素にtoUpperCase()メソッドを適用した結果で構成されるStreamを生成します。

List myList = Stream.of("a", "b")
  .map(String::toUpperCase)
  .collect(Collectors.toList());
assertEquals(asList("A", "B"), myList);

map()は、このような単純なケースでは非常にうまく機能しますが、入力としてリストのリストなど、より複雑なものがある場合はどうでしょうか。

仕組みを見てみましょう。

List> list = Arrays.asList(
  Arrays.asList("a"),
  Arrays.asList("b"));
System.out.println(list);

このスニペットは、リスト[[a], [b]].のリストを出力します。次に、flatMap()を使用しましょう。

System.out.println(list
  .stream()
  .flatMap(Collection::stream)
  .collect(Collectors.toList()));

このようなスニペットの結果は、[a, b].にフラット化されます

TheflatMap()メソッドは、最初にStreamsの入力StreamStringsStreamにフラット化します(フラット化の詳細については、%(t6 )s)。 その後は、map()メソッドと同様に機能します。

4. 結論

Java 8は、関数型言語で元々使用されていたmap()およびflatMap()メソッドを使用する機会を提供します。

Streamsとオプションでそれらを呼び出すことができます。 これらのメソッドは、提供されたマッピング関数を適用することにより、マップされたオブジェクトを取得するのに役立ちます。

いつものように、この記事over on GitHubで提供されている例を確認できます。