Java收集器按动态字段分组

问题描述 投票:3回答:1

我有以下嵌套的groupingBy块:

Map<String,Map<String,Long>> namesCountersMap =
            events.stream().collect(
                Collectors.groupingBy(
                    namesDAO::getName,
                    Collectors.groupingBy(
                        genericDAO::SOME_DYNAMIC_FIELD,
                        Collectors.counting())
                )
            );

有一种情况我需要调用这个块3次,我唯一要改变的是内部groupingBy字段(“SOME_DYNAMIC_FIELD”)。

基本上我正在尝试做的是,每次使用分组并计算不同的字段(在第二级),然后合并结果。

例:

{
      "NamesRecords": {
        "Sam": {
            "Cars": 4
            "Bags": 6 
            "Houses": 2 
        },

        "Bob": {
            "Cars": 2
            "Bags": 1 
            "Houses": 3 
        },

      }
}

如您所见,第二级的分组由3个不同的字段完成,这就是为什么我需要复制这个代码块三次。

如果我将fieldToGroupBy的参数传递给函数,有没有办法可以动态使用它?或者,如果您对如何避免代码重复有任何其他想法,我很乐意听到。

java spring collections group-by collectors
1个回答
3
投票

Collectors.groupingBy的第一个参数是Function<T,R>,因此您可以使用该类型的变量。

它只是一个函数接口,带有一个用于将值提取到group by的方法,它可以通过方法引用,lambda表达式,匿名类或任何其他类型的类来实现。

Function<namesDAO, String> classifier2 = genericDAO::SOME_DYNAMIC_FIELD;

Map<String,Map<String,Long>> namesCountersMap =
        events.stream().collect(
            Collectors.groupingBy(
                namesDAO::getName,
                Collectors.groupingBy(
                    classifier2,
                    Collectors.counting())
            )
        );

现在,您可以为classifier2指定不同的值,例如

Function<namesDAO, String> classifier2 = someDAO::getCars;

Function<namesDAO, String> classifier2 = otherDAO::getBags;

Function<namesDAO, String> classifier2 = dao -> dao.getHouses();
© www.soinside.com 2019 - 2024. All rights reserved.