Pretty-print a Map in Java

前端 未结 16 933
傲寒
傲寒 2020-12-04 10:11

I am looking for a nice way to pretty-print a Map.

map.toString() gives me: {key1=value1, key2=value2, key3=value3}

I

相关标签:
16条回答
  • 2020-12-04 10:27

    Look at the code for HashMap#toString() and AbstractMap#toString() in the OpenJDK sources:

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

    So if the guys from OpenJDK did not find a more elegant way to do this, there is none :-)

    0 讨论(0)
  • 2020-12-04 10:27

    You should be able to do what you want by doing:

    System.out.println(map) for example

    As long as ALL your objects in the map have overiden the toString method you would see:
    {key1=value1, key2=value2} in a meaningfull manner

    If this is for your code, then overiding toString is a good habit and I suggest you go for that instead.

    For your example where your objects are Strings you should be fine without anything else.
    I.e. System.out.println(map) would print exactly what you need without any extra code

    0 讨论(0)
  • 2020-12-04 10:32

    Have a look at the Guava library:

    Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("=");
    System.out.println(mapJoiner.join(map));
    
    0 讨论(0)
  • 2020-12-04 10:32

    Does not answer exactly the question, but it is worth mentioning Lombodok @ToString annotation. If you annotate with @ToString the key / value classes, then doing System.out.println(map) will return something meaningful.

    It also works very well with maps-of-maps, for example: Map<MyKeyClass, Map<String, MyValueClass>> will be printed as

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

    0 讨论(0)
  • 2020-12-04 10:34

    As a quick and dirty solution leveraging existing infrastructure, you can wrap your uglyPrintedMap into a java.util.HashMap, then use 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 讨论(0)
  • 2020-12-04 10:36

    Or put your logic into a tidy little class.

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

    Usage:

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

    Note: You can also put that logic into a utility method.

    0 讨论(0)
提交回复
热议问题