150

我正在寻找一种漂亮的打印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();

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

4

16 回答 16

317
Arrays.toString(map.entrySet().toArray())
于 2013-10-28T15:35:22.233 回答
75

看看 Guava 库:

Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("=");
System.out.println(mapJoiner.join(map));
于 2013-10-15T12:03:49.220 回答
65

或者把你的逻辑放到一个整洁的小课堂上。

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

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

于 2012-04-12T08:57:13.157 回答
41

Apache 库来救援!

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

所有你需要的 Apache commons-collections 库(项目链接

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

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>
于 2014-02-19T14:17:01.847 回答
20

当我org.json.JSONObject在类路径中时,我会:

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

(这很好地缩进了可能嵌套的列表、集合和地图)

于 2015-06-05T06:28:47.517 回答
19

简单易行。欢迎来到 JSON 世界。使用谷歌的 Gson

new Gson().toJson(map)

具有 3 个键的地图示例:

{"array":[null,"Some string"],"just string":"Yo","number":999}
于 2015-06-11T06:48:17.337 回答
14

使用 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);
于 2017-09-14T14:31:49.137 回答
10

我更喜欢将地图转换为 JSON 字符串:

  • 一个标准
  • 人类可读
  • 在 Sublime、VS Code 等编辑器中受支持,具有语法高亮、格式化和部分隐藏/显示
  • 支持 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 "";
    }
    
于 2017-10-13T18:48:07.170 回答
4

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

因此,如果来自 OpenJDK 的人没有找到更优雅的方法来做到这一点,那就没有 :-)

于 2012-04-12T09:05:56.317 回答
3

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

System.out.println(map)例如

只要地图中的所有对象都覆盖了toString您将看到的方法:
{key1=value1, key2=value2}以有意义的方式

如果这适用于您的代码,那么重写toString是一个好习惯,我建议您改为这样做。

对于你的例子,你的对象是Strings 你应该没问题。
System.out.println(map)无需任何额外代码即可准确打印您需要的内容

于 2012-04-12T08:52:35.423 回答
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);
}
于 2013-01-26T19:36:00.140 回答
1

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 将 Jackson JSON 添加到您的类路径中。

于 2019-07-04T13:57:13.470 回答
1

从 java 8 开始,使用 Lambda 可以很容易地做到这一点:

yourMap.keySet().forEach(key -> {
    Object obj = yourMap.get(key);
    System.out.println( obj);
}
于 2020-04-19T09:56:04.587 回答
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();

我知道必须删除最后一个逗号很难看,但我认为它比此解决方案中的替代方案或手动使用迭代器更干净。

于 2012-04-12T09:00:14.040 回答
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
于 2013-09-26T10:47:02.853 回答
0

没有准确回答问题,但值得一提的是 Lombodok @ToString annotation。如果您使用类进行注释,@ToString那么key / valueSystem.out.println(map)将返回一些有意义的东西。

它也适用于地图的地图,例如: Map<MyKeyClass, Map<String, MyValueClass>>将打印为

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

于 2018-09-07T08:22:46.930 回答