用Java漂亮地打印地图

时间:2021-12-29 21:47:37

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

我正在寻找一种漂亮的方法来打印地图。

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

tostring()给出:{key1=value1, key2=value2, key3=value3}

I want more freedom in my map entry values and am looking for something more like this: key1="value1", key2="value2", key3="value3"

我希望在映射条目值中有更大的*度,我正在寻找更类似的东西:key1="value1" key2="value2" key3="value3"

I wrote this little piece of code:

我写了一小段代码:

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

But I am sure there is a more elegant and concise way to do this.

但我相信,有一种更优雅、更简洁的方式可以做到这一点。

13 个解决方案

#1


52  

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.

注意:您还可以将该逻辑放入实用程序方法中。

#2


234  

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

#3


59  

Have a look at the Guava library:

看看番石榴图书馆:

Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("=");
System.out.println(mapJoiner.join(map));

#4


25  

Apache libraries to the rescue!

Apache库的拯救!

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

All you need Apache commons-collections library (project link)

所有您需要的Apache common -collections库(项目链接)

Maven users can add the library using this dependency:

Maven用户可以使用这个依赖项添加库:

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

#5


8  

When I have org.json.JSONObject in the classpath, I do:

当我有org.json。在类路径中的JSONObject,我这样做:

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

(this beautifully indents lists, sets and maps which may be nested)

(这个漂亮的缩进列表、集合和映射可以嵌套)

#6


7  

Simple and easy. Welcome to the JSON world. Using Google's Gson:

简单和容易。欢迎来到JSON世界。使用谷歌Gson:

new Gson().toJson(map)

Example of map with 3 keys:

3个键的地图示例:

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

#7


4  

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

查看OpenJDK源中的HashMap#toString()和AbstractMap#toString()代码:

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 :-)

因此,如果OpenJDK的人没有找到一种更优雅的方式来实现这一点,那么就没有:-)

#8


3  

I prefer to convert the map to a JSON string it is:

我倾向于将映射转换为JSON字符串,它是:

  • a standard
  • 一个标准的
  • human readable
  • 人类可读的
  • supported in editors like Sublime, VS Code, with syntax highlighting, formatting and section hide/show
  • 支持编辑,如崇高,VS代码,语法突出,格式和节隐藏/显示
  • supports JPath so editors can report exactly which part of the object you have navigated to
  • 支持JPath,编辑器可以准确地报告您导航到的对象的哪个部分
  • supports nested complex types within the object

    支持对象内嵌套的复杂类型

    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 "";
    }
    

#9


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

#10


1  

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

你应该能够做你想做的事:

System.out.println(map) for example

例如System.out.println(map)

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

只要映射中的所有对象都对toString方法进行了重载,您就可以看到:{key1=value1, key2=value2}的含义是完整的

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

如果这是您的代码,那么overiding toString是一个好习惯,我建议您改用它。

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

在你的例子中,你的对象是字符串,你应该没有其他的东西。例如,System.out.println(map)将打印您需要的内容,而不需要任何额外的代码

#11


1  

Using Java 8 Streams:

使用Java 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);

#12


0  

I guess something like this would be cleaner, and provide you with more flexibility with the output format (simply change template):

我想类似这样的东西会更简洁,并为您提供更灵活的输出格式(简单地更改模板):

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

I know having to remove the last comma is ugly, but I think it's cleaner than alternatives like the one in this solution or manually using an iterator.

我知道要删除最后一个逗号是很难看的,但是我认为它比在这个解决方案中使用的方法更干净,或者使用迭代器来手动。

#13


0  

As a quick and dirty solution leveraging existing infrastructure, you can wrap your uglyPrintedMap into a java.util.HashMap, then use toString().

作为一个利用现有基础设施的快速而又脏的解决方案,您可以将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

#1


52  

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.

注意:您还可以将该逻辑放入实用程序方法中。

#2


234  

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

#3


59  

Have a look at the Guava library:

看看番石榴图书馆:

Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("=");
System.out.println(mapJoiner.join(map));

#4


25  

Apache libraries to the rescue!

Apache库的拯救!

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

All you need Apache commons-collections library (project link)

所有您需要的Apache common -collections库(项目链接)

Maven users can add the library using this dependency:

Maven用户可以使用这个依赖项添加库:

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

#5


8  

When I have org.json.JSONObject in the classpath, I do:

当我有org.json。在类路径中的JSONObject,我这样做:

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

(this beautifully indents lists, sets and maps which may be nested)

(这个漂亮的缩进列表、集合和映射可以嵌套)

#6


7  

Simple and easy. Welcome to the JSON world. Using Google's Gson:

简单和容易。欢迎来到JSON世界。使用谷歌Gson:

new Gson().toJson(map)

Example of map with 3 keys:

3个键的地图示例:

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

#7


4  

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

查看OpenJDK源中的HashMap#toString()和AbstractMap#toString()代码:

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 :-)

因此,如果OpenJDK的人没有找到一种更优雅的方式来实现这一点,那么就没有:-)

#8


3  

I prefer to convert the map to a JSON string it is:

我倾向于将映射转换为JSON字符串,它是:

  • a standard
  • 一个标准的
  • human readable
  • 人类可读的
  • supported in editors like Sublime, VS Code, with syntax highlighting, formatting and section hide/show
  • 支持编辑,如崇高,VS代码,语法突出,格式和节隐藏/显示
  • supports JPath so editors can report exactly which part of the object you have navigated to
  • 支持JPath,编辑器可以准确地报告您导航到的对象的哪个部分
  • supports nested complex types within the object

    支持对象内嵌套的复杂类型

    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 "";
    }
    

#9


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

#10


1  

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

你应该能够做你想做的事:

System.out.println(map) for example

例如System.out.println(map)

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

只要映射中的所有对象都对toString方法进行了重载,您就可以看到:{key1=value1, key2=value2}的含义是完整的

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

如果这是您的代码,那么overiding toString是一个好习惯,我建议您改用它。

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

在你的例子中,你的对象是字符串,你应该没有其他的东西。例如,System.out.println(map)将打印您需要的内容,而不需要任何额外的代码

#11


1  

Using Java 8 Streams:

使用Java 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);

#12


0  

I guess something like this would be cleaner, and provide you with more flexibility with the output format (simply change template):

我想类似这样的东西会更简洁,并为您提供更灵活的输出格式(简单地更改模板):

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

I know having to remove the last comma is ugly, but I think it's cleaner than alternatives like the one in this solution or manually using an iterator.

我知道要删除最后一个逗号是很难看的,但是我认为它比在这个解决方案中使用的方法更干净,或者使用迭代器来手动。

#13


0  

As a quick and dirty solution leveraging existing infrastructure, you can wrap your uglyPrintedMap into a java.util.HashMap, then use toString().

作为一个利用现有基础设施的快速而又脏的解决方案,您可以将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