Java Collectors按动态字段分组

时间:2019-04-12 16:09:05

标签: java spring collections group-by collectors

我有以下嵌套的groupingBy块:

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

在某些情况下,我需要调用此块3次,唯一更改的是内部分组字段(“ SOME_DYNAMIC_FIELD”)。

基本上,我想做的是每次使用分组方式并在另一个字段(第二级)进行计数,然后合并结果。

示例:

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

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

      }
}

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

如果我将fieldToGroupBy的参数传递给函数,是否可以动态使用它?或者,如果您对避免代码重复还有其他想法,我很想听听。

1 个答案:

答案 0 :(得分:3)

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

它只是一个功能接口,具有用于提取要分组的值的方法,并且可以通过方法引用,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();