我有一个字符串列表,其中每个字符串由字母组成,这些字母由字符“,”(逗号)分隔。 我想遍历字符串列表,以逗号分隔,计算每个字母出现多少次,并将结果存储在Multiset中。空白字符串应被忽略,并且拆分部分应修剪。多重集应按键排序。
以下代码有效,即,它产生所需的多集。但是,我无法弄清楚如何使用适当的收集器方法(Multisets.toMultiset()),因此诉诸于两步解决方案,使用了一个我想消除的临时列表变量。
如果有人可以告诉我如何在收集步骤中构造对Multisets.toMultiset()的调用,我将不胜感激。我陷入了定义元素函数和供应商函数的困境,我什至无法编写已编译的代码...
@Test
public void testIt() {
List<String> temp = Stream.of("b, c", "a", " ", "a, c")
.filter(StringUtils::isNotBlank)
.map(val -> val.split(","))
.flatMap(Arrays::stream)
.map(String::trim)
.collect(Collectors.toList());
Multiset<String> multiset = ImmutableSortedMultiset.copyOf(temp);
System.out.println("As list: " + temp);
System.out.println("As multiset: " + multiset);
// Output is:
// As list: [b, c, a, a, c]
// As multiset: [a x 2, b, c x 2]
}
我正在使用番石榴28.1。上面的示例中还使用了commons-lang3版本3.9中的StringUtils类
这是实际情况中的简化示例,但仍然可以捕捉到我的问题的本质
答案 0 :(得分:5)
如果您真的想省略第二个复制阶段,则有几种方法可以实现:
已经指定了一个ImmatbleSortedMultiset
收集器
.collect(ImmutableSortedMultiset.toImmutableSortedMultiset(Comparator.naturalOrder()));
因为您一直在问如何使用MultiSets::toMultiset
.collect(Multisets.toMultiset(Function.identity(), i -> 1, TreeMultiset::create));
或者您可以使用Builder
.collect(Collector.of(
ImmutableSortedMultiset::<String>naturalOrder,
ImmutableSortedMultiset.Builder::add,
(b1, b2) -> {b1.addAll(b2.build()); return b1;},
ImmutableSortedMultiset.Builder::build)
);