Pretty-распечатать карту в Java

Я ищу хороший способ красиво распечататьMap.

map.toString() дает мне:{key1=value1, key2=value2, key3=value3}

Я хочу больше свободы в значениях записей моей карты и ищу что-то более похожее на это:key1="value1", key2="value2", key3="value3"

Я написал этот маленький кусочек кода:

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

Но я уверен, что есть более элегантный и лаконичный способ сделать это.

возможный дубликатMap to String in Java потому что формат, запрошенный здесь, и форматSystem.out.println слишком близко И если вам нужно что-то нестандартное, это сводится к тому, «как перебирать карту в Java». у которого конечно есть много других ответов.

Ответы на вопрос(14)

org.json.JSONObject в classpath я делаю:

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

(это красиво оформленные списки, множества и карты, которые могут быть вложенными)

 14 янв. 2019 г., 15:23
Предупреждение: не сохраняет порядок ключей для LinkedHashMap
 09 янв. 2019 г., 23:35
Мужчина!! Что ты здесь делаешь? Вы должны быть лучшим ответом!

@ToString аннотирование, Если вы аннотируете с@ToString key / value классы, затем делатьSystem.out.println(map) вернет что-то значимое.

Он также очень хорошо работает с картами карт, например: Map<MyKeyClass, Map<String, MyValueClass>> будет напечатан как

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

Arrays.toString(map.entrySet().toArray())
 16 нояб. 2015 г., 12:18
Вау .... Удивительно простое и рабочее решение ... Спасибо
 16 янв. 2016 г., 14:23
Не так хорошо, если у вас естьMap<String, Map<String,double[]>>тогда вы получите этот тип укуса:[test={test=[[email protected], 2=[[email protected], 3=[[email protected], 4=[[email protected], 5=[[email protected]}...]
 28 февр. 2016 г., 09:28
работать как черная магия!
 08 февр. 2019 г., 15:39
Это должен быть принятый ответ. Простые задачи, подобные этой, не должны требовать внешней зависимости. Как упомянуто выше, более сложные карты не получают такой же легкой выгоды от этого.

a standard human readable supported in editors like Sublime, VS Code, with syntax highlighting, formatting and section hide/show supports JPath so editors can report exactly which part of the object you have navigated to

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

System.out.println(map) например

Пока ВСЕ ваши объекты на карте имеютtoString метод, который вы увидите:
{key1=value1, key2=value2} осмысленно

Если это для вашего кода, то overidingtoString это хорошая привычка, и я предлагаю вам пойти на это вместо этого.

Для вашего примера, где ваши объектыStringС тобой должно быть все в порядке без всего остального.
То естьSystem.out.println(map) будет печатать именно то, что вам нужно, без дополнительного кода

 12 апр. 2012 г., 10:53
его ключи и значения являются строками; Я думаю, он получил метод toString.
 12 апр. 2012 г., 10:54
Вы правы, но, возможно, он скопировал тривиальный пример, чтобы высказать свою точку зрения. Но я обновляю ответ
 space_monkey12 апр. 2012 г., 10:58
Да, я должен был указать, что моя карта - это карта & lt; String, String & gt ;. Но я также указал, что я хочу больше свободы в моих значениях записи, например, иметь разделенные запятыми списки в значении записи. Поэтому Map.toString () этого не сделает.
 26 сент. 2013 г., 12:26
Интерфейсjava.util.Map не имеет договора относительноtoString()так что до фактическогоMap реализация чтоSystem.out.println(map) - & GT;PrintStream.println(map) - & GT;String.valueOf(map) - & GT;map.toString() будет вызывать. Бывает, что часто используемыеjava.util.AbstractMap обеспечивает хорошее строковое представление дляtoString(), ... ДругойMap реализации могут отступить кObject.toString()что приводит к не очень информативным[email protected].
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);
}

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

Все, что вам нужно, библиотека Apache commons-collection (ссылка на проект)

Пользователи Maven могут добавить библиотеку, используя эту зависимость:

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>
 06 февр. 2019 г., 12:54
или log.debug (& quot; Map: {} & quot ;, MapUtils.toProperties (map));
 19 окт. 2016 г., 10:49
Это не обрабатывает массивы как значения карты (например,Map<String, String[]>). Только их className и hash печатаются вместо фактических значений.

использующее существующую инфраструктуру, вы можете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

что-то вроде этого будет чище, и даст вам больше гибкости с выходным форматом (просто измените шаблон):

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

Я знаю, что убирать последнюю запятую - это ужасно, но я думаю, что она чище, чем альтернативы, такие какв этом решении или вручную с помощью итератора.

Решение Вопроса

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

Примечание. Вы также можете поместить эту логику в служебный метод.

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 не нашли более элегантный способ сделать это, то их нет :-)

Google's Gson:

new Gson().toJson(map)

Пример карты с 3 ключами:

{"array":[null,"Some string"],"just string":"Yo","number":999}
 16 окт. 2018 г., 08:35
Почему отрицательный голос?

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

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

System.out.println(content);
 14 сент. 2017 г., 17:29
Если вы собираетесь ответить на вопрос, по крайней мере, ответьте правильно! Вы пропускаете кавычки вокруг значения, и к нему следует присоединиться, используя,

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

Ваш ответ на вопрос