Как удобно менять клавиши и значения на карте

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

Я прочитал этот пост, к сожалению, в нем нет элегантных решений. У меня также нет возможности использовать какие-либо причудливые Guava BiMaps или что-либо за пределами jdk (стек проекта уже определен).

Я могу предположить, что моя карта биективна, btw:)

6 ответов

Стандартная среда выполнения API/Java не предлагает двунаправленную карту, поэтому единственное решение - перебирать все записи и вручную менять их.

Что вы можете сделать, так это создать класс-оболочку, который содержит две карты и который выполняет двойную put() внутренне, чтобы у вас было бы быстрое представление двух данных.

[EDIT] Кроме того, благодаря открытому исходному коду вам не нужно включать стороннюю библиотеку, вы можете просто скопировать нужные вам классы в свой собственный проект.


Если у вас нет выбора использовать стороннюю библиотеку, я не считаю этот код настолько уродливым (хотя некоторые языки сценариев имеют изящные способы сделать это):

//map must be a bijection in order for this to work properly
public static <k,v> HashMap<v,k> reverse(Map<k,v> map) {
 HashMap<v,k> rev = new HashMap<v, k="">();
 for(Map.Entry<k,v> entry : map.entrySet())
 rev.put(entry.getValue(), entry.getKey());
 return rev;
}
</k,v></v,></v,k></k,v></v,k></k,v>


Map<string, integer=""> map = new HashMap<>();
Map<integer, string=""> swapped = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
</integer,></string,>


Карты не похожи на списки, которые можно отменить путем замены головы хвостом.

Объекты на картах имеют вычисленную позицию, и использование значения как ключа и ключа как значения потребует повторного вычисления места хранения, необходимо создать еще одну карту. Нет элегантного способа.

Существуют, однако, двунаправленные карты. Это может удовлетворить ваши потребности. Я бы пересмотрел использование сторонних библиотек.


Есть некоторые задания, которые могут быть упрощены до определенного момента и не более. Это может быть один из них!

Если вы хотите выполнить задание с использованием Java-коллекций apis, тогда грубая сила - это путь, который будет быстрым (если коллекция не будет огромной), и это будет очевидный фрагмент кода.


Как подсказка ответить qaru.site/questions/428417/...

Это работает только в том случае, если карта не является HashMap и не содержит повторяющихся значений.

Map<string,string> newMap = oldMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
</string,string>

генерирует исключение

java.lang.IllegalStateException: Дублирующий ключ

если есть значения более одного раза.

Решение:

HashMap<string,string> newMap = new HashMap<>();
for(Map.Entry<string,string> entry : oldMap.entrySet())
 newMap.put(entry.getValue(), entry.getKey());
// Add inverse to old one
oldMap.putAll(newMap);
</string,string></string,string>

licensed under cc by-sa 3.0 with attribution.