Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как поменять местами ключи и значения в Map

Короткий ответ

Пройдите по парам и соберите новую Map, где ключ и значение поменялись местами:

void main() {
    Map<String, Integer> codes = Map.of("DE", 49, "FR", 33, "IT", 39);
 
    Map<Integer, String> byNumber = codes.entrySet().stream()
            .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey, (a, b) -> a, TreeMap::new));
    IO.println(byNumber);
}

Результат:

{33=FR, 39=IT, 49=DE}

Повторяющиеся значения

Если одно значение встречается у нескольких ключей, соберите ключи в список через groupingBy():

void main() {
    var cities = new TreeMap<>(Map.of("Berlin", "DE", "Munich", "DE", "Paris", "FR"));
 
    Map<String, List<String>> byCountry = cities.entrySet().stream()
            .collect(Collectors.groupingBy(Map.Entry::getValue, TreeMap::new,
                    Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
    IO.println(byCountry);
}

Результат:

{DE=[Berlin, Munich], FR=[Paris]}

Циклом

Тот же разворот без потоков:

void main() {
    var colors = new LinkedHashMap<String, String>();
    colors.put("red", "#f00");
    colors.put("green", "#0f0");
 
    var byHex = new LinkedHashMap<String, String>();
    colors.forEach((name, hex) -> byHex.put(hex, name));
    IO.println(byHex);
}

Результат:

{#f00=red, #0f0=green}

Частая ошибка

Использовать toMap() без функции слияния, когда значения повторяются. Два одинаковых ключа вызывают исключение:

void main() {
    var cities = new TreeMap<>(Map.of("Berlin", "DE", "Munich", "DE"));
    var inverted = cities.entrySet().stream()
            .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
}

Результат:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key DE (attempted merging values Berlin and Munich)

Передайте третьим аргументом правило слияния, например (a, b) -> a + ", " + b, или используйте groupingBy().

Функции из этого ответа

  • Collectors.toMap() — Сборщик, который строит словарь из элементов потока.
  • Collectors.groupingBy() — Сборщик, который раскладывает элементы по группам с общим ключом.
  • Map.entrySet() — Возвращает все пары «ключ — значение» для обхода.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.