Tania
Tania

Reputation: 1925

Java8 streams and filters

I have a set multimap that stores some strings against a month(integer).

MonthlyCount = {1:["hello"],2:["hello","hi"]}   

I have a map that counts the number of strings per month and adds them. I use containsKey filter to check if the key is present in the collection, and add them to the map.

final String[] months = new DateFormatSymbols().getShortMonths();
final Map<String, Object> metaData = new LinkedHashMap<>();
private SetMultimap<Integer, String> MonthlyCount;

for (int i = 0; i <= month; i++) {
    final int count = MonthlyCount.containsKey(i + 1) ? MonthlyCount.get(i + 1).size() : 0;
    metaData.put(months[i], count);
}

Is there a way to achieve the same behavior with Java8's streams and filters ?

Upvotes: 3

Views: 291

Answers (2)

Holger
Holger

Reputation: 298103

Note that you are doing unnecessary work. Have look at SetMultimap.get:

Returns a view collection of the values associated with key in this multimap, if any. Note that when containsKey(key) is false, this returns an empty collection, not null.

So all you need to do in your loop, is

metaData.put(months[i], MonthlyCount.get(i + 1).size());

as it will be zero for absent keys anyway. If you have a non-guava Map<…,Set<…>>, you could do an equivalent operation in Java 8:

metaData.put(months[i], MonthlyCount.getOrDefault(i + 1, emptySet()).size());

where emptySet() is a static import of Collections.emptySet().

I wouldn’t rewrite the loop to use a stream when you want to add to an existing Map. After all, the code is concise enough

for(int i=0; i<month.length; i++)
    metaData.put(months[i], MonthlyCount.get(i + 1).size());

and won’t become better with a stream…

Upvotes: 4

Eran
Eran

Reputation: 393771

You can use an IntStream to iterate over the required range and use Collectors.toMap to produce the required map :

Map<String,Integer> map =
IntStream.range(0,months.length)
         .boxed()
         .collect(Collectors.toMap(i->months[i], 
                                   i->MonthlyCount.containsKey(i + 1) ? MonthlyCount.get(i + 1).size() : 0));

Upvotes: 5

Related Questions