簡體   English   中英

將 POJO 轉換為 Java 8 中的樹結構,以分層結構表示數據

[英]Convert a POJO to Tree structure in Java 8 for representation of data in hierarchical structure

我有一個List<CropDetailDto>postgresql 中本機查詢的Hibernate Projection返回。

我想以分層/樹格式表示它以將其作為響應發送。

我在List<CropDetailDto>上使用了多個嵌套的Collectors.groupingBy

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()))));
}

這將返回以下地圖:

{
    "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": {}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM