web-dev-qa-db-ja.com

Javaでstream()。collectを使用して2つのリストで構成されるマップを作成

たとえば、2つのリストがあります。

List<Double> list1 = Arrays.asList(1.0, 2.0);
List<String> list2 = Arrays.asList("one_point_zero", "two_point_zero");

Streamを使用して、これらのリストで構成されるマップを作成します。ここで、list1はキー用で、list2は値用です。それを行うには、補助リストを作成する必要があります。

List<Integer> list0 = Arrays.asList(0, 1);

これが地図です:

Map<Double, String> map2 = list0.stream()
                .collect(Collectors.toMap(list1::get, list2::get));

list0は、list1 :: getおよびlist2 :: getが機能する順序で使用されます。 list0を作成せずにもっと簡単な方法はありますか?次のコードを試してみましたが、機能しませんでした。

Map<Double, String> map2 = IntStream
                .iterate(0, e -> e + 1)
                .limit(list1.size())
                .collect(Collectors.toMap(list1::get, list2::get));
9
sva605

インデックスを保持するために補助リストを使用する代わりに、IntStreamによってインデックスを生成することができます。

Map<Double, String> map = IntStream.range(0, list1.size())
            .boxed()
            .collect(Collectors.toMap(i -> list1.get(i), i -> list2.get(i)));
16
svarog

実際、最良のアプローチは、両方のリストの各要素に IntStream.range(startInclusive, endExclusive) を使用してアクセスし、最後に get(index) を使用することです。 Math.min(a, b) リストがまったく同じサイズでない場合にIndexOutOfBoundsExceptionを取得しないようにするため、最終的なコードは次のようになります。

Map<Double, String> map2 = IntStream.range(0, Math.min(list1.size(), list2.size()))
    .boxed()
    .collect(Collectors.toMap(list1::get, list2::get));
8
Nicolas Filotto

これは私にとってはうまくいきますが、O(n ^ 2)です:

    Map<Double, String> collect =
            list1.stream()
                    .collect(
                            toMap(Double::doubleValue, 
                                    item -> list2.get(list1.indexOf(item))));
4
Sergii Getman