在 Java 8 流 API 中按计数分组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25441088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Group by counting in Java 8 stream API
提问by Muhammad Hewedy
I try to find a simple way in Java 8 stream API to do the grouping, I come out with this complex way!
我尝试在 Java 8 流 API 中找到一种简单的方法来进行分组,我提出了这种复杂的方法!
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Hello");
list.add("World");
Map<String, List<String>> collect = list.stream().collect(
Collectors.groupingBy(o -> o));
System.out.println(collect);
List<String[]> collect2 = collect
.entrySet()
.stream()
.map(e -> new String[] { e.getKey(),
String.valueOf(e.getValue().size()) })
.collect(Collectors.toList());
collect2.forEach(o -> System.out.println(o[0] + " >> " + o[1]));
I appreciate your input.
我感谢您的意见。
采纳答案by Jon Skeet
I think you're just looking for the overloadwhich takes another Collector
to specify what to do with each group... and then Collectors.counting()
to do the counting:
我认为你只是在寻找需要另一个来指定每个组做什么的重载Collector
......然后Collectors.counting()
进行计数:
import java.util.*;
import java.util.stream.*;
class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Hello");
list.add("World");
Map<String, Long> counted = list.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted);
}
}
Result:
结果:
{Hello=2, World=1}
(There's also the possibility of using groupingByConcurrent
for more efficiency. Something to bear in mind for your real code, if it would be safe in your context.)
(还有可能groupingByConcurrent
用于提高效率。如果在您的上下文中是安全的,请记住您的真实代码。)
回答by Sivakumar
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Hello");
list.add("World");
Map<String, List<String>> collect = list.stream()
.collect(Collectors.groupingBy(o -> o));
collect.entrySet()
.forEach(e -> System.out.println(e.getKey() + " - " + e.getValue().size()));
回答by user_3380739
回答by fjkjava
Here is example for list of Objects
这是对象列表的示例
Map<String, Long> requirementCountMap = requirements.stream().collect(Collectors.groupingBy(Requirement::getRequirementType, Collectors.counting()));
回答by Ousmane D.
Here are slightly different options to accomplish the task at hand.
以下是完成手头任务的略有不同的选项。
using toMap
:
使用toMap
:
list.stream()
.collect(Collectors.toMap(Function.identity(), e -> 1, Math::addExact));
using Map::merge
:
使用Map::merge
:
Map<String, Integer> accumulator = new HashMap<>();
list.forEach(s -> accumulator.merge(s, 1, Math::addExact));
回答by Donald Raab
If you're open to using a third-party library, you can use the Collectors2
class in Eclipse Collectionsto convert the List
to a Bag
using a Stream
. A Bag
is a data structure that is built for counting.
如果你打开使用第三方库,你可以使用Collectors2
类的Eclipse收藏到转换List
至Bag
使用Stream
。ABag
是为计数而构建的数据结构。
Bag<String> counted =
list.stream().collect(Collectors2.countBy(each -> each));
Assert.assertEquals(1, counted.occurrencesOf("World"));
Assert.assertEquals(2, counted.occurrencesOf("Hello"));
System.out.println(counted.toStringOfItemToCount());
Output:
输出:
{World=1, Hello=2}
In this particular case, you can simply collect
the List
directly into a Bag
.
在这种特殊情况下,你可以简单的collect
将List
直接进入Bag
。
Bag<String> counted =
list.stream().collect(Collectors2.toBag());
You can also create the Bag
without using a Stream
by adapting the List
with the Eclipse Collections protocols.
您还可以创建Bag
不使用Stream
通过调整List
与Eclipse集合协议。
Bag<String> counted = Lists.adapt(list).countBy(each -> each);
or in this particular case:
或者在这种特殊情况下:
Bag<String> counted = Lists.adapt(list).toBag();
You could also just create the Bag directly.
您也可以直接创建 Bag。
Bag<String> counted = Bags.mutable.with("Hello", "Hello", "World");
A Bag<String>
is like a Map<String, Integer>
in that it internally keeps track of keys and their counts. But, if you ask a Map
for a key it doesn't contain, it will return null
. If you ask a Bag
for a key it doesn't contain using occurrencesOf
, it will return 0.
ABag<String>
类似于 a Map<String, Integer>
,因为它在内部跟踪键及其计数。但是,如果您向 a 请求Map
它不包含的密钥,它将返回null
。如果您向 a 请求Bag
它不包含 using 的密钥occurrencesOf
,它将返回 0。
Note:I am a committer for Eclipse Collections.
注意:我是 Eclipse Collections 的提交者。