Java 将字符串集合简化为发生映射

问题描述 投票:0回答:4

将列表视为

id1_f, id2_d, id3_f, id1_g
,我如何使用流来获取
<String, Integer>
格式的简化地图统计数据,例如:

id1 2
id2 1
id3 1

注:关键是

_
之前的部分。
reduce
函数可以帮忙吗?

java mapreduce java-stream
4个回答
7
投票

这将完成工作:

Map<String, Long> map = Stream.of("id1_f", "id2_d", "id3_f", "id1_g")
  .collect(
    Collectors.groupingBy(v -> v.split("_")[0],
    Collectors.counting())
  );

0
投票

您还可以使用

toMap
收集器:

myList.stream()
      .collect(Collectors.toMap((String s) -> s.split("_")[0], 
                   (String s) -> 1, Math::addExact);

如果您关心元素的顺序,请将结果转储到

LinkedHashMap
中。

myList.stream()
      .collect(Collectors.toMap((String s) -> s.split("_")[0], 
                   (String s) -> 1, Math::addExact, 
                     LinkedHashMap::new));

0
投票

使用 Map::merge:

的非流方法
Map<String, Integer> result = new LinkedHashMap<>();
myList.forEach(s -> result.merge(s.split("_")[0], 1, Math::addExact));

0
投票

既然你想要count元素,我建议使用Guava

Multiset
界面,它专门用于此目的。

JavaDoc 中

Multiset
的定义:

支持与顺序无关的相等性的集合,如

Set
,但可能有重复的元素。多重集有时也称为 bag

多重集中彼此相等的元素被称为同一单个元素的“出现”。多重集中某个元素出现的总次数称为该元素的 count

这里有两种使用方法:

1) 没有 Stream API:

ImmutableMultiset<String> multiset2 = ImmutableMultiset.copyOf(Lists.transform( list, str -> StringUtils.substringBefore(str, "_") ));

2) 使用 Stream API:

ImmutableMultiset<String> multiset = list.stream() .map(str -> StringUtils.substringBefore(str, "_")) .collect(ImmutableMultiset.toImmutableMultiset());

请注意,我没有使用 
s.split("_")[0]

之类的东西,而是使用了

Apache Commons Lang
StringUtils.substringBefore
,我发现它更具可读性。
您可以使用

Multiset.count()

 方法检索元素的计数。

© www.soinside.com 2019 - 2024. All rights reserved.