मेरे पास postgresql में एक मूल क्वेरी के हाइबरनेट प्रोजेक्शन द्वारा लौटाया गया List<CropDetailDto> है।

मैं इसे प्रतिक्रिया के रूप में भेजने के लिए इसे पदानुक्रमित/पेड़ प्रारूप में प्रस्तुत करना चाहता हूं।

मैंने 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": {}
}

यानी, अगर कोई नल कुंजी है तो मैं इसे अगली प्रविष्टि में ले जाना चाहता हूं।

मैंने हाल ही में जावा 8 का उपयोग करना शुरू किया है, मैं उपरोक्त संरचना को प्राप्त करने के लिए एक संक्षिप्त तरीका ढूंढ रहा हूं।

फसल विवरण डीटीओ:

public interface CropDetailDto {

    Long getCropId();

    String getCropName();

    Long getVarietyId();

    String getVarietyName();

    Long getSubVarietyId();

    String getSubVarietyName();
}

परिणामी वापसी प्रकार एक साधारण HashMap<String, Object> भी हो सकता है। साथ ही, यदि Java 8 सुविधाओं का उपयोग करके इसे प्राप्त करना संभव नहीं है, तो कृपया java 8 के बिना इसे लागू करने का तरीका प्रदान करें।

अग्रिम में धन्यवाद।

2
Mohammed Idris 17 जुलाई 2019, 10:34

1 उत्तर

सबसे बढ़िया उत्तर

आप अंतिम Collectors.groupingBy() के बजाय Collectors.mapping() का उपयोग कर सकते हैं:

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": {}
}
1
Samuel Philipp 18 जुलाई 2019, 17:38