我有Thing对象的列表:
Error
class Thing {
public String id;
public String name;
}
包含以下内容;
List<Thing> lst
现在,我想使用Java流或任何util函数来获取id的不同计数: 我希望输出为
[{'1', 'AB'},{'2', 'CD'},{'1', 'AB'},{'1','AB'},{'2','CD'},{'3','EF'}]
我该如何实现?
答案 0 :(得分:3)
您可以使用Collectors.groupingBy
,id
属性,然后counting
,将其出现为:
List<Thing> objects = new ArrayList<>(); // initalise as in the question
Map<String, Long> countForId = objects.stream()
.collect(Collectors.groupingBy(Thing::getId, Collectors.counting()));
答案 1 :(得分:0)
一个人也可以使用toMap
收集器:
lst.stream().collect(toMap(Thing::getId, v -> 1, Math::addExact));
创建一个Map<String, Integer>
,其中Thing::getId
是用于选择映射键的键映射器,而v -> 1
是用于选择映射值的值映射器,如果是键发生冲突时,我们使用合并函数Math::addExact
添加相应的值。
或Map :: merge:
Map<String, Integer> accumulator = new HashMap<>();
lst.forEach(t -> accumulator.merge(t.getId(), 1, Math::addExact));
与上述相同,如果Thing::getId
映射中已经存在accumulator
,则将它们与Math::addExact
合并,否则我们将提供的键和值累积到映射中。
如果顺序与帖子中显示的顺序有关,则可以使用HashMap
代替上面的LinkedHashMap
。
您还可以通过以下方式提供一个映射,在其中将元素累积到其中以保持toMap
收集器中的顺序:
lst.stream().collect(toMap(Thing::getId, v -> 1, Math::addExact, LinkedHashMap::new));
或使用groupingBy
收集器:
lst.stream()
.collect(Collectors.groupingBy(Thing::getId,
LinkedHashMap::new,
Collectors.counting()));