如何在 Java 中使用流创建两个数组的映射?

问题描述 投票:0回答:4

假设我有两个

Double

数组
Double[] a = new Double[]{1.,2.,3.};
Double[] b = new Double[]{10.,20.,30.};

使用 Java 流,如何创建一个将两个数组组合在一起的映射 (

Map<Double,Double> myCombinedMap;
),例如通过以下方式:

System.out.println(myCombinedMap);
{1.0=10.0, 2.0=20.0, 3.0=30.0}

我想正在寻找类似于带有 Java 流的 Python zip 的东西,或者一个优雅的解决方法。

我认为这个问题与this一个不同(指出可能重复) 因为它以 Java8 流为中心,而在提出可能的重复问题时,这些流还不可用。

java java-stream
4个回答
8
投票

使用

IntStream
并收集到地图:

IntStream.range(0, a.length)
         .boxed()
         .collect(toMap(i -> a[i], i -> b[i]));

1
投票

我可能会寻求青峰本人的解决方案。为了完整起见,如果你不喜欢

IntStream
的拳击(感觉没必要),你可以这样做:

    Double[] a = new Double[]{1.,2.,3.};
    Double[] b = new Double[]{10.,20.,30.};

    Map<Double, Double> myMap = IntStream.range(0, a.length)
            .collect(HashMap::new, (m, i) -> m.put(a[i], b[i]), Map::putAll);
    System.out.println(myMap);

此片段的输出是:

{1.0=10.0, 2.0=20.0, 3.0=30.0}

就代码而言,Aomine 的代码和我的代码之间有一个重要的区别:该代码会检查重复的键和对象(如果有)。我的代码默认删除它们。我的代码也可以扩展以包含检查,但这会增加我认为我们不想要的复杂性。

为什么

boxed()
调用有帮助:Aomine 使用
Collectors
toMap
类中的收集器仅适用于对象流,而不是像
IntStream
这样的基元流。


0
投票

我们可以使用提供索引的

Collectors.toMap()
中的
IntStream
来做到这一点:

Double[] a = new Double[]{1.,2.,3.};
Double[] b = new Double[]{10.,20.,30.};

Map<Double, Double> map = 
IntStream.range(0, a.length)
          //If you array has null values this will remove them 
         .filter(idx -> a[idx] != null && b[idx] != null)
         .mapToObj(idx -> idx)
         .collect(Collectors.toMap(idx -> a[idx], idx -> b[idx]));

我们还可以将

IntStream
映射到
Map.Entry<Double, Double>
对象流,然后使用
Collectors.toMap()
:

Double[] a = new Double[]{1.,2.,3.};
Double[] b = new Double[]{10.,20.,30.};

Map<Double, Double> map = 
IntStream.range(0, a.length)
          .filter(idx -> a[idx] != null && b[idx] != null)
          .mapToObj(idx -> new AbstractMap.SimpleEntry<Double, Double>(a[idx], b[idx]))
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

0
投票

Google Guava 库有

Streams.zip
方法,它将压缩两个流:

Map<Double, Double> myCombinedMap =
        Streams.zip(Arrays.stream(a), Arrays.stream(b), Map::entry)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
© www.soinside.com 2019 - 2024. All rights reserved.