首页 文章

如何使用Java流查找不同对象的计数

提问于
浏览
2

我有一个Thing对象列表:

class Thing {
    public String id;
    public String name;
}

List<Thing> lst 包含以下内容;

[{'1', 'AB'},{'2', 'CD'},{'1', 'AB'},{'1','AB'},{'2','CD'},{'3','EF'}]

现在我想使用Java流或任何util函数来获取id的独特计数:我想要输出,

id   count
1    3
2    2 
3    1

我怎样才能做到这一点?

2 回答

  • 0

    一个人也可以使用 toMap 收藏家:

    lst.stream().collect(toMap(Thing::getId, v -> 1, Math::addExact));
    

    创建 Map<String, Integer> ,其中 Thing::getId 是用于选择 Map 键的键映射器, v -> 1 是用于选择映射值的值映射器,在键碰撞的情况下,我们使用合并函数 Math::addExact 添加相应的值 .

    或Map :: merge:

    Map<String, Integer> accumulator = new HashMap<>();
    lst.forEach(t -> accumulator.merge(t.getId(), 1, Math::addExact));
    

    与上面相同的想法,如果 accumulator 已经出现在 accumulator Map 中,我们将它们与 Math::addExact 合并,否则我们将提供的键和值累积到 Map 中 .

    如果您的帖子中显示的订单很重要,那么您可以使用 LinkedHashMap 而不是上面的 HashMap .

    您还可以提供要将元素累积到的 Map ,以保留 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()));
    
  • 4

    您可以使用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()));
    

相关问题