Довольно печатать карту в 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();
Но я уверен, что есть более элегантный и лаконичный способ сделать это.
Ответы
Ответ 1
Или добавьте свою логику в аккуратный маленький класс.
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));
Примечание. Вы также можете поместить эту логику в метод утилиты.
Ответ 2
Arrays.toString(map.entrySet().toArray())
Ответ 3
Посмотрите на библиотеку Guava:
Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("=");
System.out.println(mapJoiner.join(map));
Ответ 4
Библиотеки Apache на помощь!
MapUtils.debugPrint(System.out, "myMap", map);
Все, что вам нужно для библиотеки коллекций коллекций Apache (ссылка проекта)
Пользователи Maven могут добавить библиотеку, используя эту зависимость:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
Ответ 5
Просто и легко. Добро пожаловать в мир JSON. Используя Google Gson:
new Gson().toJson(map)
Пример карты с 3 ключами:
{"array":[null,"Some string"],"just string":"Yo","number":999}
Ответ 6
Когда у меня есть org.json.JSONObject
в пути к классам, я делаю:
Map<String, Object> stats = ...;
System.out.println(new JSONObject(stats).toString(2));
(это прекрасный список отступов, множеств и карт, которые могут быть вложенными)
Ответ 7
Я предпочитаю преобразовать карту в строку JSON:
- стандартный
- читаемый человеком
- поддерживается в редакторах, таких как Sublime, VS Code, с синтаксисом
подсветка, форматирование и секция hide/show
- поддерживает 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 "";
}
Ответ 8
Использование потоков 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);
Ответ 9
Посмотрите код 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 не нашли более элегантный способ сделать это, их нет: -)
Ответ 10
Вы должны делать то, что хотите, делая:
System.out.println(map)
например
Пока ВСЕ ваши объекты на карте превышают метод toString
, вы увидите:
{key1=value1, key2=value2}
значимым образом
Если это для вашего кода, то переопределение toString
- хорошая привычка, и я предлагаю вам пойти на это вместо этого.
В вашем примере, где ваши объекты String
, вы должны быть в порядке, не имея ничего другого.
То есть System.out.println(map)
будет печатать именно то, что вам нужно без дополнительного кода
Ответ 11
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);
}
Ответ 12
Я думаю, что-то вроде этого было бы более чистым и обеспечило бы большую гибкость в формате вывода (просто измените шаблон):
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();
Я знаю, что удаление последней запятой является уродливым, но я думаю, что он чище, чем альтернативы, такие как в этом решении или вручную с помощью итератора.
Ответ 13
В качестве быстрого и грязного решения, использующего существующую инфраструктуру, вы можете обернуть 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
Ответ 14
Точно не отвечает на этот вопрос, но стоит упомянуть аннотацию Lombodok @ToString
. Если вы аннотируете с помощью @ToString
key/value
, то выполнение System.out.println(map)
вернет что-то значимое.
Он также очень хорошо работает с картами карт, например: Map<MyKeyClass, Map<String, MyValueClass>>
будет напечатан как
{MyKeyClass(properties...)={string1=MyValuesClass(properties...), string2=MyValuesCalss(properties...),..},... }
Ответ 15
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 добавьте Джексона JSON в ваш путь к классам.