Say I have two arrays of Double
Double[] a = new Double[]{1.,2.,3.};
Double[] b = new Double[]{10.,20.,30.};
Using Java streams , how do I create a map ( Map<Double,Double> myCombinedMap;
) that combines the two arrays for example in the following way:
System.out.println(myCombinedMap);
{1.0=10.0, 2.0=20.0, 3.0=30.0}
I guess am looking for something similar to Python zip with Java streams, or an elegant workaround.
I think this question differs from this one (pointed out as possible duplicate) because is centered on Java8 streams, which were not yet available at the time the possible duplicate question was asked.
use IntStream
and collect to a map:
IntStream.range(0, a.length)
.boxed()
.collect(toMap(i -> a[i], i -> b[i]));
I'd probably go for the solution by Aomine myself. For the sake of completeness, if you don't like the boxing of the IntStream
(it feels unnecessary), you may do for example:
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);
Output from this snippet is:
{1.0=10.0, 2.0=20.0, 3.0=30.0}
As the code stands, there is an important difference between the working of the code by Aomine and my code though: That code checks for duplicate keys and objects if there are any. My code tacitly drops them. My code could be extended to include the check too, but it would add a complication that I don't think we want.
Why the boxed()
call helps: the collectors in the Collectors
class, of which Aomine used toMap
, work only on streams of objects, not on streams of primitives like IntStream
.
We can do it using Collectors.toMap()
from an IntStream
which supplies the indices:
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]));
We could also map the IntStream
to a Stream of Map.Entry<Double, Double>
objects then use 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));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.