Pretty-печать карты на Java
Я ищу хороший способ довольно-печать 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();
но я уверен, что есть более элегантный и лаконичный способ сделать это.
14 ответов:
или поместите свою логику в аккуратный маленький класс.
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));Примечание: Вы также можете поместить эту логику в метод утилит.
взгляните на библиотеку гуавы:
Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("="); System.out.println(mapJoiner.join(map));
библиотеки Apache на помощь!
MapUtils.debugPrint(System.out, "myMap", map);все, что вам нужно Apache commons-collections library ( ссылка на проект)
пользователи Maven могут добавить библиотеку, используя эту зависимость:
<dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency>
когда у меня есть
org.json.JSONObjectв classpath, я делаю:Map<String, Object> stats = ...; System.out.println(new JSONObject(stats).toString(2));(это красиво отступы, списки, наборы и карты, которые могут быть вложенными)
просто и легко. Добро пожаловать в мир JSON. Используя Gson от Google:
new Gson().toJson(map)пример карты с 3 ключами:
{"array":[null,"Some string"],"just string":"Yo","number":999}
Я предпочитаю конвертировать карту в строку 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 ""; }
посмотреть код
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 не нашли более элегантный способ сделать это, нет ни одного: -)
Использование 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);
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); }
вы должны быть в состоянии сделать то, что вы хотите делать:
пока все ваши объекты на карте имеют overiden
toStringспособ вы увидите:{key1=value1, key2=value2}в осмысленной манереесли это для вашего кода, то overiding
toString- это хорошая привычка и я предлагаю вам пойти на это.для вашего примера, где ваши объекты
Strings Вы должны быть в порядке без чего-либо еще.
Т. е.System.out.println(map)будет печатать именно то, что вам нужно без какого-либо дополнительного кода
Я думаю, что-то вроде этого было бы чище, и предоставить вам больше гибкости с форматом вывода (просто изменить шаблон):
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();Я знаю, что удаление последней запятой уродливо, но я думаю, что это чище, чем альтернативы, такие как один в данном решении или вручную с помощью итератора.
как быстрое и грязное решение, использующее существующую инфраструктуру, вы можете обернуть свой
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
не отвечает точно на вопрос, но стоит отметить, Lombodok
@ToStringаннотации. Если вы комментируете с@ToStringthekey / valueклассы, а затем делатьSystem.out.println(map)вернет что-то значимое.он также очень хорошо работает с картами карт, например:
Map<MyKeyClass, Map<String, MyValueClass>>будет напечатано как
{MyKeyClass(properties...)={string1=MyValuesClass(properties...), string2=MyValuesCalss(properties...),..}, ... }
Comments