Как переопределить = symbol при преобразовании HashMap в строку с использованием метода toString?

#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 : .