java - 将 POJO 转换为 Java 8 中的树结构以在层次结构中表示数据

标签 java collections java-8 spring-data-jpa treeview

我有一个 List<CropDetailDto>postgresql 中的 native 查询的 Hibernate Projection 返回。

我想以层次结构/树 格式表示它以将其作为响应发送。

我使用了多个嵌套 Collectors.groupingByList<CropDetailDto>

public Map<String, Map<String, Map<String, List<CropDetailDto>>>> findCropDetails() {
        List<CropDetailDto> cropdetails = cropRepository.getCropDetails();
        return cropdetails.stream().collect(Collectors.groupingBy(CropDetailDto::getCropName, Collectors.groupingBy(
                v -> v.getVarietyName() == null ? "undefined" : v.getVarietyName(),
                Collectors.groupingBy(m -> m.getSubVarietyName() == null ? "undefined" : m.getSubVarietyName()))));
    }

我以某种方式能够以这种格式表示数据。

{
  "Tomato": {
    "Red Tomato": {
      "Red Tomato 1 quality": [
        {
          "cropName": "Tomato",
          "varietyName": "Red Tomato",
          "subVarietyName": "Red Tomato 1 quality",
          "varietyId": 1002,
          "cropId": 1,
          "subVarietyId": 1003           //cropDetailDto is again represented 
                                          //at the leaf level
        }
      ],
      "Red Tomato 2 quality": [
        {
          "cropName": "Tomato",
          "varietyName": "Red Tomato",
          "subVarietyName": "Red Tomato 2 quality",
          "varietyId": 1002,
          "cropId": 1,
          "subVarietyId": 1004
        }
      ]
    }
  },
  "Brinjal": {
    "undefined": {
      "undefined": [
        {
          "cropName": "Brinjal",
          "varietyName": null,
          "subVarietyName": null,
          "varietyId": null,
          "cropId": 8,
          "subVarietyId": null
        }
      ]
    }
  }
}

然而,这个表示有undefined作为键,因为它为空键抛出 NPE。

我想以更清晰的格式表示相同的数据。

是这样的:

{
  "Tomato": {
    "Red Tomato": [
      "Red Tomato 1 quality",
      "Red Tomato 2 quality"
    ]
  },
  "Brinjal": {}
}

即 如果有一个空键,我希望它移动到下一个条目。

我最近开始使用java 8,我正在寻找一种简洁的方法来实现上述结构。

CropDetailDto:

public interface CropDetailDto {

    Long getCropId();

    String getCropName();

    Long getVarietyId();

    String getVarietyName();

    Long getSubVarietyId();

    String getSubVarietyName();
}

结果返回类型也可以是一个简单的 HashMap<String, Object> . 此外,如果无法使用 Java 8 功能 实现此目的,请提供一种无需 java 8 即可实现此目的的方法。

提前致谢。

最佳答案

您可以使用 Collectors.mapping() 而不是最后一个 Collectors.groupingBy():

public Map<String, Map<String, List<String>>> findCropDetails() {
    List<CropDetailDto> cropdetails = cropRepository.getCropDetails();
    return cropdetails.stream().collect(Collectors.groupingBy(CropDetailDto::getCropName,
            Collectors.groupingBy(v -> v.getVarietyName() == null ? "undefined" : v.getVarietyName(),
                    Collectors.mapping(m -> m.getSubVarietyName() == null ? "undefined" : m.getSubVarietyName(),
                            Collectors.toList()))));
}

这将返回以下 map :

{
    "Tomato": {
        "Red Tomato": [
            "Red Tomato 1 quality", 
            "Red Tomato 2 quality"
        ]
    }, 
    "Brinjal": {
        "undefined": [
            "undefined"
        ]
    }
}

要从结果中删除 null 值,您可以使用 Collectors.filtering() 并稍微修改上面的代码:

public Map<String, Map<String, List<String>>> findCropDetails() {
    List<CropDetailDto> cropdetails = cropRepository.getCropDetails();
    return cropdetails.stream().collect(Collectors.groupingBy(CropDetailDto::getCropName,
            Collectors.filtering(v -> v.getVarietyName() != null, Collectors.groupingBy(CropDetailDto::getVarietyName,
                    Collectors.filtering(m -> m.getSubVarietyName() != null, Collectors.mapping(CropDetailDto::getSubVarietyName,
                            Collectors.toList()))))));
}

使用它的最终结果将如下所示:

{
    "Tomato": {
        "Red Tomato": [
            "Red Tomato 1 quality", 
            "Red Tomato 2 quality"
        ]
    }, 
    "Brinjal": {}
}

关于java - 将 POJO 转换为 Java 8 中的树结构以在层次结构中表示数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57070740/

相关文章:

java - 检查一个节点在 jsoup 中是否有明文?

java - oracle.sql.ARRAY 和 oracle.sql.ArrayDescriptor 的通用实现

java - 我们如何在 Solr 中获取集群级别的指标?

collections - 关闭的集合。不同的调用方式。

Java 8 嵌套 null 检查列表中映射中的字符串

sorting - 按反转值对 Map<String, Long> 进行排序

java - 使用合并排序从文本文件中读取的 100000 个整数的反转计数。但无法获得正确的反转计数

java - 如何将值从excel存储到java中的某个集合

java - Java中两个对象列表之间的区别

java - 将方法作为参数传递并在 forEach 循环中使用