HashMap के मूल्यों को पुनरावृत्त और कॉपी करने का कुशल तरीका


9

मैं रूपांतरित करना चाहता हूं:

Map<String, Map<String, List<Map<String, String>>>> inputMap 

सेवा:

Map<String, Map<String, CustomObject>> customMap

inputMap विन्यास में प्रदान किया गया है और तैयार है लेकिन मुझे इसकी आवश्यकता है customMap प्रारूपित । CustomObject List<Map<String, String>>एक फ़ंक्शन में कोड की कुछ पंक्तियों का उपयोग करने से प्राप्त होगा ।

मैंने इनपुट मानचित्र को पुनरावृत्त करने और customMap में प्रमुख मानों की प्रतिलिपि बनाने का एक सामान्य तरीका आज़माया है। क्या जावा 8 या किसी अन्य शॉर्टकट का उपयोग करने का कोई कुशल तरीका है?

Map<String, Map<String, List<Map<String, String>>>> configuredMap = new HashMap<>();
Map<String, Map<String, CustomObj>> finalMap = new HashMap<>();


for (Map.Entry<String, Map<String, List<Map<String, String>>>> attributeEntry : configuredMap.entrySet()) {
    Map<String, CustomObj> innerMap = new HashMap<>();
    for (Map.Entry<String, List<Map<String, String>>> valueEntry : attributeEntry.getValue().entrySet()) {
        innerMap.put(valueEntry.getKey(), getCustomeObj(valueEntry.getValue()));
    }
    finalMap.put(attributeEntry.getKey(), innerMap);
}

private CustomObj getCustomeObj(List<Map<String, String>> list) {
    return new CustomObj();
}

कृपया कोड को ठीक से प्रारूपित करें।
akuzminykh

1
क्या आपने नक़ल करने के बजाए एक मुखौटा बनाने के बारे में सोचा है?
कंट्रोलएटलडेल

कोई और अधिक कुशल तरीका नहीं हो सकता। उन सभी ऑपरेशनों को करना है। लेकिन यह कोड वास्तव में काम नहीं करता है। आप सूची को कस्टम ऑब्जेक्ट में नहीं डाल रहे हैं।
user207421

जवाबों:


2

एक समाधान के लिए स्ट्रीम करना entrySetहै inputMap, और फिर Collectors#toMapदो बार (बाहरी के Mapलिए एक बार, और एक बार भीतर के लिए Map) का उपयोग करें:

Map<String, Map<String, CustomObj>> customMap = inputMap.entrySet()
        .stream()
        .collect(Collectors.toMap(Function.identity(), entry -> {
            return entry.getValue()
                        .entrySet()
                        .stream()
                        .collect(Collectors.toMap(Function.identity(), 
                            entry -> getCustomeObj(entry.getValue())));
        }));

आप {}.collect(Collectors.toMap(Function.identity(), entry -> entry.getValue() .entrySet() .stream() .collect(Collectors.toMap(Function.identity(), entry -> getCustomeObj(entry.getValue()))); ));
लाम्बदा

3
@ शको सच, लेकिन मुझे लगता है कि यह ब्लॉक के बिना कम पठनीय लगेगा।
जैकब जी

1

आप स्ट्रीम कर सकते हैं, लेकिन यह देखने योग्य नहीं है; कम से कम मेरे लिए। तो अगर आपके पास एक विधि है:

static CustomObject fun(List<Map<String, String>> in) {
    return .... // whatever processing you have here
}

आप अभी भी java-8वाक्य रचना का उपयोग कर सकते हैं , लेकिन एक अलग रूप में:

    Map<String, Map<String, CustomObject>> customMap = new HashMap<>();

    inputMap.forEach((key, value) -> {

        value.forEach((innerKey, listOfMaps) -> {

            Map<String, CustomObject> innerMap = new HashMap<>();
            innerMap.put(innerKey, fun(listOfMaps));
            customMap.put(key, innerMap);

        });
    });

यदि आप आंतरिक नक्शा बना सकते हैं, तो आप इसे और immutableभी छोटा कर सकते हैं:

inputMap.forEach((key, value) -> {
      value.forEach((innerKey, listOfMaps) -> {
          customMap.put(key, Collections.singletonMap(innerKey, fun(listOfMaps)));
      });
});

1

IMHO स्ट्रीमिंग इतना बुरा विचार नहीं है। कोई बुरा उपकरण नहीं हैं। यह इस बात पर निर्भर करता है कि आप उनका उपयोग कैसे कर रहे हैं।


इस विशेष मामले में मैं दोहराव पैटर्न को एक उपयोगिता विधि में निकालूंगा:

public static <K, V1, V2> Map<K, V2> transformValues(Map<K, V1> map, Function<V1, V2> transformer) {
    return map.entrySet()
              .stream()
              .collect(toMap(Entry::getKey, e -> transformer.apply(e.getValue())));
}

ऊपर दी गई विधि को किसी भी दृष्टिकोण का उपयोग करके लागू किया जा सकता है, हालांकि मुझे लगता है कि Stream APIयहां बहुत अच्छी तरह से फिट बैठता है।


एक बार जब आप उपयोगिता विधि को परिभाषित करते हैं, तो इसे निम्नानुसार सरल रूप में इस्तेमाल किया जा सकता है:

Map<String, Map<String, CustomObj>> customMap = 
    transformValues(inputMap, attr -> transformValues(attr, this::getCustomObj));

वास्तविक परिवर्तन प्रभावी रूप से एक लाइनर है। तो विधि के JavaDocलिए उचित के साथ transformValuesपरिणाम कोड बहुत पठनीय और बनाए रखने योग्य है।


1

Collectors.toMapबाहरी और भीतरी दोनों स्तरों पर प्रविष्टियों के बारे में कैसे :

Map<String, Map<String, CustomObj>> finalMap = configuredMap.entrySet()
        .stream()
        .collect(Collectors.toMap(Map.Entry::getKey,
                attributeEntry -> attributeEntry.getValue().entrySet()
                        .stream()
                        .collect(Collectors.toMap(Map.Entry::getKey,
                                valueEntry -> getCustomeObj(valueEntry.getValue())))));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.