在Java8中将POJO转换为树结构,以便以层次结构表示数据

在Java8中将POJO转换为树结构,以便以层次结构表示数据,java,collections,java-8,spring-data-jpa,treeview,Java,Collections,Java 8,Spring Data Jpa,Treeview,我有一个列表,由postgresql中本机查询的Hibernate投影返回 我想用层次/树格式表示它,将其作为响应发送 我使用了多个嵌套的收集器 但是,此表示具有未定义的作为键,因为它为空键抛出了NPE 我希望以更清晰的格式表示相同的数据 大概是这样的: { "Tomato": { "Red Tomato": [ "Red Tomato 1 quality", "Red Tomato 2 quality" ] }, "Brinjal": {}

我有一个
列表
,由postgresql中本机查询的Hibernate投影返回

我想用层次/树格式表示它,将其作为响应发送

我使用了多个嵌套的
收集器

但是,此表示具有未定义的
作为键,因为它为空键抛出了NPE

我希望以更清晰的格式表示相同的数据

大概是这样的:

{
  "Tomato": {
    "Red Tomato": [
      "Red Tomato 1 quality",
      "Red Tomato 2 quality"
    ]
  },
  "Brinjal": {}
}
i、 e。, 如果有一个空键,我希望它移动到下一个条目

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

CropDetailDto:

public interface CropDetailDto {

    Long getCropId();

    String getCropName();

    Long getVarietyId();

    String getVarietyName();

    Long getSubVarietyId();

    String getSubVarietyName();
}
结果返回类型也可以是简单的
HashMap
。 另外,如果使用Java 8功能无法实现这一点,请提供一种在不使用Java 8的情况下实现这一点的方法


提前感谢。

您可以使用
Collectors.mapping()
而不是最后一个
收集器。groupingBy()

要从结果中删除
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()))))));
}

您的解决方案消除了leaf-
“undefined”:[{“cropName”:“Brinjal”,“varietyName”:null,“subVarietyName”:null,“varietyId”:null,“cropId”:8,“subVarietyId”:null}
但是,我不希望使用
未定义的
作为键。如果键为
null
,则代码应
继续
到下一个循环。如果子品种为null,我希望括号为空。
{}
@MohammedIdris是的,你是对的。忘记处理这个问题了。我更新了我的答案并添加了一个扩展解决方案,它删除了
null
值。
public interface CropDetailDto {

    Long getCropId();

    String getCropName();

    Long getVarietyId();

    String getVarietyName();

    Long getSubVarietyId();

    String getSubVarietyName();
}
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"
        ]
    }
}
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": {}
}