简体   繁体   中英

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 ?

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));

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…

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM