सुंदर जावा में एक नक्शा मुद्रित करें


136

मैं सुंदर प्रिंट करने के लिए एक अच्छा तरीका के लिए देख रहा हूँ Map

map.toString() मुझे देता है: {key1=value1, key2=value2, key3=value3}

मैं अपने मानचित्र प्रविष्टि मूल्यों में और अधिक स्वतंत्रता चाहता हूं और कुछ इस तरह की तलाश कर रहा हूं: key1="value1", key2="value2", key3="value3"

मैंने इस छोटे से कोड को लिखा है:

StringBuilder sb = new StringBuilder();
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
    Entry<String, String> entry = iter.next();
    sb.append(entry.getKey());
    sb.append('=').append('"');
    sb.append(entry.getValue());
    sb.append('"');
    if (iter.hasNext()) {
        sb.append(',').append(' ');
    }
}
return sb.toString();

लेकिन मुझे यकीन है कि ऐसा करने का एक और अधिक सुंदर और संक्षिप्त तरीका है।


1
जावा में स्ट्रिंग टू मैप का संभव डुप्लिकेट क्योंकि प्रारूप यहाँ अनुरोध किया गया है और जो System.out.printlnबहुत करीब हैं। और अगर आप कुछ कस्टम चाहते हैं, तो यह "जावा में नक्शे पर कैसे पुनरावृत्त करना है" के लिए उबालता है, जिसमें निश्चित रूप से कई अन्य उत्तर हैं।
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 '

जवाबों:


63

या अपने तर्क को एक छोटे से वर्ग में रखें।

public class PrettyPrintingMap<K, V> {
    private Map<K, V> map;

    public PrettyPrintingMap(Map<K, V> map) {
        this.map = map;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        Iterator<Entry<K, V>> iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Entry<K, V> entry = iter.next();
            sb.append(entry.getKey());
            sb.append('=').append('"');
            sb.append(entry.getValue());
            sb.append('"');
            if (iter.hasNext()) {
                sb.append(',').append(' ');
            }
        }
        return sb.toString();

    }
}

उपयोग:

Map<String, String> myMap = new HashMap<String, String>();

System.out.println(new PrettyPrintingMap<String, String>(myMap));

नोट: आप उस तर्क को एक उपयोगिता विधि में भी डाल सकते हैं।


3
यह एक एंटीपैटर्न इमहो है। आप अपने प्रकार के लिए एक मजबूत बाधा (वंशानुक्रम) जोड़ते हैं, बस पेटीएम लाभों (सुंदर मुद्रण) के लिए। आप नियमित नक्शे का उपयोग करना बेहतर होगा, लेकिन एक स्थिर पद्धति का उपयोग करें जो इसे एक तर्क के रूप में लेती है।
OoDeLally

304
Arrays.toString(map.entrySet().toArray())

11
इतना अच्छा नहीं अगर आपके पास है Map<String, Map<String,double[]>>, तो आपको इस प्रकार का स्टिंग मिलेगा:[test={test=[D@3995ebd8, 2=[D@26fa5067, 3=[D@1d956d37, 4=[D@2cead81, 5=[D@14934d2b}...]
zygimantus

2
यह स्वीकृत उत्तर होना चाहिए। इस तरह के सरल कार्यों के लिए बाहरी निर्भरता की आवश्यकता नहीं होनी चाहिए। जैसा कि ऊपर उल्लेख किया गया है, अधिक जटिल नक्शे इससे बहुत आसानी से लाभ नहीं उठाते हैं।
शादिनिजा


34

बचाव के लिए अपाचे पुस्तकालय!

MapUtils.debugPrint(System.out, "myMap", map);

अपाचे कॉमन्स-संग्रह पुस्तकालय ( परियोजना लिंक ) की आपको आवश्यकता है

मावेन उपयोगकर्ता इस निर्भरता का उपयोग करके पुस्तकालय को जोड़ सकते हैं:

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>

यह मानचित्र के मानों (जैसे। Map<String, String[]>) के रूप में सरणियों को नहीं संभालता है । केवल उनका वर्गनाम और हैश वास्तविक मूल्यों के बजाय मुद्रित होता है।
पेट्र Petजेद्स्कस्की

या log.debug ("मानचित्र: {}", MapUtils.toProperties (नक्शा));
charlb

1
इसके अलावा काम MapUtils.verbosePrint है, जो डिबगप्रिंट आउटपुट के प्रत्येक मान के बाद वर्ग नाम को छोड़ देगा।
ओकार्लसन

16

सरल और आसान। JSON दुनिया में आपका स्वागत है। Google के Gson का उपयोग करना :

new Gson().toJson(map)

3 कुंजी के साथ नक्शे का उदाहरण:

{"array":[null,"Some string"],"just string":"Yo","number":999}

15

जब मेरे पास org.json.JSONObjectकक्षा है, मैं करता हूं:

Map<String, Object> stats = ...;
System.out.println(new JSONObject(stats).toString(2));

(यह खूबसूरती से सूचियों, सेटों और नक्शों को दर्शाता है, जिन्हें घोंसला बनाया जा सकता है)


1
आदमी!! आप यहाँ क्या कर रहे हैं? आप शीर्ष जवाब होना चाहिए!
दुखद

चेतावनी: एक लिंक्डहाशपैप के लिए कुंजियों के क्रम को संरक्षित नहीं करता है
ओलिवियर

9

जावा 8 स्ट्रीम का उपयोग करना:

Map<Object, Object> map = new HashMap<>();

String content = map.entrySet()
                    .stream()
                    .map(e -> e.getKey() + "=\"" + e.getValue() + "\"")
                    .collect(Collectors.joining(", "));

System.out.println(content);

2
यदि आप एक प्रश्न को लागू करने जा रहे हैं, तो कम से कम इसका सही उत्तर दें! आप मान के आसपास के उद्धरणों को याद कर रहे हैं और इसे ,
AjahnCharles

8

मैं मानचित्र को JSON स्ट्रिंग में बदलना पसंद करता हूं:

  • एक मानक
  • मानव पठनीय
  • सिंटैक्स हाइलाइटिंग, स्वरूपण और अनुभाग छिपाने / शो के साथ सबलाइम, वीएस कोड जैसे संपादकों में समर्थित है
  • JPath का समर्थन करता है, इसलिए संपादक ठीक उसी तरह से रिपोर्ट कर सकते हैं कि आपने किस वस्तु का हिस्सा नेविगेट किया है
  • ऑब्जेक्ट के भीतर नेस्टेड जटिल प्रकारों का समर्थन करता है

    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public static String getAsFormattedJsonString(Object object)
    {
        ObjectMapper mapper = new ObjectMapper();
        try
        {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
        }
        catch (JsonProcessingException e)
        {
            e.printStackTrace();
        }
        return "";
    }

4

के लिए कोड को देखो HashMap#toString()और AbstractMap#toString()OpenJDK स्रोतों में:

class java.util.HashMap.Entry<K,V> implements Map.Entry<K,V> {
       public final String toString() {
           return getKey() + "=" + getValue();
       }
   }
 class java.util.AbstractMap<K,V> {
     public String toString() {
         Iterator<Entry<K,V>> i = entrySet().iterator();
         if (! i.hasNext())
            return "{}";

        StringBuilder sb = new StringBuilder();
        sb.append('{');
        for (;;) {
            Entry<K,V> e = i.next();
            K key = e.getKey();
            V value = e.getValue();
            sb.append(key   == this ? "(this Map)" : key);
            sb.append('=');
            sb.append(value == this ? "(this Map)" : value);
            if (! i.hasNext())
                return sb.append('}').toString();
            sb.append(", ");
        }
    }
}

तो अगर OpenJDK के लोगों को ऐसा करने के लिए अधिक सुरुचिपूर्ण तरीका नहीं मिला, तो कोई भी नहीं है :-)


3

आपको वह करने में सक्षम होना चाहिए जो आप कर रहे हैं:

System.out.println(map) उदाहरण के लिए

जब तक नक्शे में आपकी सभी वस्तुएं आपके द्वारा देखी गई toStringविधि को ओवरडेन कर देती हैं:
{key1=value1, key2=value2}अर्थपूर्ण तरीके से

यदि यह आपके कोड के लिए है, तो ओवरईडिंग toStringएक अच्छी आदत है और मेरा सुझाव है कि आप इसके बजाय उसके लिए जाएं।

आपके उदाहरण के लिए जहां आपकी वस्तुएं हैं, Stringआपको बिना किसी चीज के ठीक होना चाहिए।
यानी System.out.println(map)आपको बिना किसी अतिरिक्त कोड के ठीक वही प्रिंट करना होगा जो आपको चाहिए


1
उसकी चाबी और मूल्य तार हैं; मुझे लगता है कि वह tohring विधि कवर tbh मिला है।
टॉम

आप सही कह रहे हैं, लेकिन शायद उन्होंने अपनी बात बनाने के लिए एक तुच्छ उदाहरण की नकल की थी। लेकिन मैं जवाब अपडेट करता हूं
Cratylus

हां, मुझे यह संकेत देना चाहिए कि मेरा नक्शा मानचित्र <स्ट्रिंग, स्ट्रिंग> है। लेकिन मैंने यह भी संकेत दिया कि मैं अपने प्रवेश मूल्यों में अधिक स्वतंत्रता चाहता हूं, उदाहरण के लिए एक प्रविष्टि के मूल्य के भीतर अल्पविराम से अलग सूची। तो Map.toString () नहीं करेंगे।
space_monkey

इंटरफ़ेस java.util.Mapका कोई अनुबंध नहीं है toString(), इसलिए यह वास्तविक Mapकार्यान्वयन तक है System.out.println(map)-> PrintStream.println(map)-> String.valueOf(map)-> map.toString()कारण होगा। ऐसा होता है कि अक्सर इस्तेमाल के java.util.AbstractMapलिए एक अच्छा स्ट्रिंग प्रतिनिधित्व प्रदान करता है toString()। ... अन्य Mapकार्यान्वयन वापस आ सकते हैं Object.toString(), जिसके परिणामस्वरूप सूचनात्मक नहीं है com.example.MyMap@4e8c0de
अब्दुल

2
public void printMapV2 (Map <?, ?> map) {
    StringBuilder sb = new StringBuilder(128);
    sb.append("{");
    for (Map.Entry<?,?> entry : map.entrySet()) {
        if (sb.length()>1) {
            sb.append(", ");
        }
        sb.append(entry.getKey()).append("=").append(entry.getValue());
    }
    sb.append("}");
    System.out.println(sb);
}

0

मुझे लगता है कि यह कुछ ऐसा होगा जो क्लीनर होगा, और आपको आउटपुट प्रारूप के साथ अधिक लचीलापन प्रदान करेगा (बस टेम्पलेट बदलें):

    String template = "%s=\"%s\",";
    StringBuilder sb = new StringBuilder();
    for (Entry e : map.entrySet()) {
        sb.append(String.format(template, e.getKey(), e.getValue()));
    }
    if (sb.length() > 0) {
        sb.deleteCharAt(sb.length() - 1); // Ugly way to remove the last comma
    }
    return sb.toString();

मुझे पता है कि अंतिम अल्पविराम को हटाना बदसूरत है, लेकिन मुझे लगता है कि यह इस समाधान में एक की तरह विकल्पों की तुलना में क्लीनर है या मैन्युअल रूप से एक पुनरावृत्ति का उपयोग कर रहा है।


0

मौजूदा बुनियादी ढांचे का लाभ उठाने वाले एक त्वरित और गंदे समाधान के रूप में, आप अपने uglyPrintedMapको इसमें लपेट सकते हैं java.util.HashMap, फिर उपयोग कर सकते हैं toString()

uglyPrintedMap.toString(); // ugly
System.out.println( uglyPrintedMap ); // prints in an ugly manner

new HashMap<Object, Object>(jobDataMap).toString(); // pretty
System.out.println( new HashMap<Object, Object>(uglyPrintedMap) ); // prints in a pretty manner

0

बिल्कुल सवाल का जवाब नहीं देता है, लेकिन यह लोम्बोडोक @ToString एनोटेशन का उल्लेख करने योग्य है । यदि आप कक्षाओं के साथ एनोटेट @ToStringकरते key / valueहैं, तो करना System.out.println(map)कुछ सार्थक लौटाएगा।

यह नक्शों के नक्शे के साथ भी बहुत अच्छा काम करता है, उदाहरण के लिए: के Map<MyKeyClass, Map<String, MyValueClass>>रूप में मुद्रित किया जाएगा

{MyKeyClass(properties...)={string1=MyValuesClass(properties...), string2=MyValuesCalss(properties...),..}, ... }


0

String result = objectMapper.writeValueAsString(map) - यह जितना आसान है!

परिणाम:

{"2019-07-04T03:00":1,"2019-07-04T04:00":1,"2019-07-04T01:00":1,"2019-07-04T02:00":1,"2019-07-04T13:00":1,"2019-07-04T06:00":1 ...}

PS अपने वर्गपथ में जैक्सन JSON जोड़ें।


0

जावा 8 के बाद से लैम्बडा के साथ इसे करने का आसान तरीका है:

yourMap.keySet().forEach(key -> {
    Object obj = yourMap.get(key);
    System.out.println( obj);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.