#java #hashmap #tostring #println
#java #hashmap #tostring #println
Вопрос:
Ниже приведена часть кода, где map инициализируется как:
Map<Integer,Integer> map = new HashMap<>();
и строка, которую я хочу изменить, является
System.out.println("Price and items " map.toString());
где в настоящее время находится вывод
{100=10,200=5}
Я хочу отобразить
{100:10,200:5}
Комментарии:
1. Вы не можете. Вы должны реализовать свой собственный метод.
2. Вы не должны использовать
toString()
для производственного кода, только для отладки. Создайте свой собственный метод вывода.3. вы можете использовать функцию форматирования строки
Ответ №1:
Не полагайтесь на метод toString()
, поскольку это деталь реализации, которая может измениться с одной версии Java на другую, вам лучше реализовать свой собственный метод.
Предполагая, что вы используете Java 8, это может быть:
public static <K, V> String mapToString(Map<K, V> map) {
return map.entrySet()
.stream()
.map(entry -> entry.getKey() ":" entry.getValue())
.collect(Collectors.joining(", ", "{", "}"));
}
Если вы хотите иметь точно такую же реализацию, AbstractMap#toString()
которая проверяет, является ли ключ или значение текущей картой, тогда код будет:
public static <K, V> String mapToString(Map<K, V> map) {
return map.entrySet()
.stream()
.map(
entry -> (entry.getKey() == map ? "(this Map)" : entry.getKey())
":"
(entry.getValue() == map ? "(this Map)" : entry.getValue()))
.collect(Collectors.joining(", ", "{", "}"));
}
Комментарии:
1. Будьте осторожны — это работает не совсем так же, как
HashMap.toString()
(по общему признанию, в некоторых довольно незначительных случаях). Проверьте источникAbstractMap.toString()
, чтобы понять, что я имею в виду.2. Вы имеете в виду
key == this ? "(this Map)" : key
илиvalue == this ? "(this Map)" : value
? Если это так, то только для того, чтобы избежать бесконечного цикла, поскольку он будет вызыватьmap.toString()
снова, что в данном случае неприменимо, поскольку он использует выделенный метод3. Я делаю — но я имею в виду, что OP запрашивает только изменение
=
на:
, поэтому вы должны сохранить существующее поведение в отношении записей с собственным ключом (или самоценностью).
Ответ №2:
Поскольку map является целым целым числом, вы можете поиграть с toString()
методом и заменить нежелательные символы…
заменить строку 🙂
map.toString().replace("=",":");
Комментарии:
1. Не работает, если у вас
=
есть ключи или значения.2. Предпочтительнее
.replace('=', ':')
, поскольку он избегает строковых литералов и не использует регулярные выражения пользователя.3.@Tom
replace
никогда не использует регулярные выражения.4. @AndyTurner Возможно, вы захотите проверить его реализацию ;). Он внутренне использует
Pattern
предоставленную строку в качестве литерала шаблона. Таким образом, он все равно компилирует это «регулярное выражение» (даже если оно не обрабатывается как регулярное выражение).5. @Tom интересно. Я этого не заметил.
Ответ №3:
Вы не можете переопределить символы в toString()
методе напрямую.
Хотя вы можете использовать String.replace
для карт, где ключи и значения не могут содержать =
(например Integer
, s), вам придется предоставить другую реализацию в целом.
Вы можете видеть, что это не так сложно сделать, если вы посмотрите на источник AbstractMap.toString()
:
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(", ");
}
}
Вы можете просто изменить значение =
to :
.