Java8流和过滤器

时间:2016-03-08 08:25:45

标签: java java-8 guava java-stream

我有一个set multimap,可以存储一些月份(整数)的字符串。

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

我有一张地图,计算每月的字符串数量并添加它们。我使用containsKey过滤器来检查密钥是否存在于集合中,并将它们添加到地图中。

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

有没有办法用Java8的流和过滤器实现相同的行为?

2 个答案:

答案 0 :(得分:5)

您可以使用IntStream来迭代所需的范围,并使用Collectors.toMap生成所需的地图:

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

答案 1 :(得分:4)

请注意,您正在做不必要的工作。看看SetMultimap.get

  

返回此多图中与key关联的值的视图集合(如果有)。请注意,如果containsKey(key)为false,则返回空集合,而不是null

所以你需要在你的循环中做的就是

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

因为无论如何它都会为零。如果你有一个非番石榴Map<…,Set<…>>,你可以在Java 8中执行相同的操作:

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

其中emptySet()Collections.emptySet()的静态导入。

当您想要添加到现有Map时,我不会重写循环以使用流。毕竟,代码足够简洁

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

并且流不会变得更好......