Reputation: 133
I have the following data set with Key is String and value as List of values.
I wanted to call a method with key and each value of list as parameters to the method. Iterate for all the keys. I am able to do it with two forEach loops as shown in my example below. I would like know if we can write the same logic using streams and flatMap in Java 8 without forEach inner loop? thanks
Map<String,ArrayList<String>> xhashMap ;
if(xhashMap!=null) {
xhashMap.forEach((k,l)-> {
if(k.equals("ax")){
l.forEach(v->{
method1(v,AA.class);
}
}
if(k.equals("bx")){
l.forEach(v->{
method1(v,BB.class);
}
}
});
}
Upvotes: 2
Views: 8797
Reputation:
Sure it can be done with flatMap and closures
xHashMap.entrySet().stream()
.flatMap(e -> e.getValue().stream()
.<Runnable>map(v -> () -> {
final String k = e.getKey();
if (k.equals("ax")) {
method1(v, AA.class);
}
if (k.equals("bx")) {
method1(v, BB.class);
}
})
)
.forEach(Runnable::run);
Upvotes: 0
Reputation: 298559
It doesn't matter whether you use a for
loop, forEach
or the Stream
API. In all cases, you are iterating over a Map
to compare each key against a certain value, which is perverting the concept of maps, to associate the key with a value and provide (usually far better that linear) lookup methods.
Further, you should use a Map<String, List<String>>
instead, not referring to an implementation type like ArrayList
, and not letting it be null
in the first place, instead of having it to check for null
later-on.
If you follow theses advice, your code becomes
Map<String, List<String>> xhashMap;
// always initialize the map to a non-null reference
xhashMap.getOrDefault("ax", Collections.emptyList())
.forEach(v -> method1(v, AA.class));
xhashMap.getOrDefault("bx", Collections.emptyList())
.forEach(v -> method1(v, BB.class));
If the map is, as the variable name suggests, a hash map, the two lookups will have O(1)
time complexity, but even a TreeMap
with O(log(n))
complexity will be better than iterating over the map and compare all keys.
As long as the action consists of a sole method invocation with different parameters, there is not much gain in trying to re-use common code, as the sharing code would be much more complicated.
Upvotes: 1
Reputation: 13873
Yes, we can't write it with Stream API, but it's not much better.
Since you are performing side effects and not collecting results, Stream
would essentially be:
xhashMap.entrySet()
.stream()
.forEach(e -> ...);
and unfortunately, contain same logic inside the forEach
.
Actually, you can even skip Stream
creation at this point because you can perform forEach
without creating a Stream
:
xhashMap.entrySet()
.forEach(e -> ...);
Upvotes: 1