👻

Stream APIを使ってJavaで複数リストをマップに変換する方法

2023/02/17に公開

Stream APIとは?

Stream APIとは、Java 8で導入された機能の一つです。Stream APIを使うことで、コレクション内の要素をフィルタリング、マッピング、リデュースするなどの操作を直感的に実現します。
また、Stream APIを利用することで並列処理が容易になり、 ラムダ式やメソッド参照などを利用して、簡潔でコンパクトなコードを書くことが可能です。

複数リストをマップに変換する

今回2つのそれぞれのリストを用意し、それぞれをkeyvalueとしてマップに変換を行います。
以下にソースコードを記載します。

import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) throws Exception {
        List<String> keys = Arrays.asList("key1", "key2", "key3");
        List<Integer> values = Arrays.asList(1, 2, 3);

        Map<String, Integer> result = IntStream.range(0, keys.size())
            .boxed()
            .collect(Collectors.toMap(keys::get, values::get));
        
        System.out.println(result);
    }
}

それぞれの処理について説明を行っていきます。

keysvaluesを構成する。2つのリストをそれぞれ宣言しています。

List<String> keys = Arrays.asList("key1", "key2", "key3");
List<Integer> values = Arrays.asList(1, 2, 3);

IntStream.range(0, keys.size())は、キーと値をマッピングするのに使用されるインデックスのストリームを作成しています。boxed()メソッドでIntStreamStream<Integer>に変換しcollect()メソッドでStream要素を集約し、今回のMapに変換しています。

Map<String, Integer> result = IntStream.range(0, keys.size())
	.boxed()
        .collect(Collectors.toMap(keys::get, values::get));

補足

  1. Collectors.toMap(keys::get, values::get))は、Collectorsクラスに用意されている toMapメソッドを使用しMapに変換する処理を行っています。
    また第1引数のkeys::getは、keysリストからインデックスに応じた要素を取得するために使用し、keys.get(i)に相当します。第2引数のvalues::getに関しても同様です。

  2. toMapメソッドは、重複するキーがある場合にIllegalStateExceptionが発生するため、重複するキーがないことに注意する必要があります。

Map<String, Integer> result = IntStream.range(0, keys.size())
        .boxed()
        .collect(Collectors.toMap(keys::get, values::get, (oldValue, newValue) -> newValue));

重複が出た場合でも以下のように書くことで、新しい値(newValue)で古い値(oldValue)を書き換えて処理することでIllegalStateExceptionを発生させないようにすることができます。

Discussion