Объединение метода удаления и вставки в LinkedHashMap - PullRequest
3 голосов
/ 21 июня 2019

С LinkedHashMap , когда я пытаюсь повторно вставить тот же ключ с другим значением, он заменяет значение и поддерживает порядок ключей, т.е. если я делаю это

Map<String,String> map = new LinkedHashMap<>();
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
map.put("d", "d");
map.values().stream().forEach(System.out::print);    

Выход: abcd

Теперь, если я добавлю на карту другое значение с тем же ключом, порядок останется прежним, т.е.

map.put("b", "j");
map.values().stream().forEach(System.out::print); 

Выход: ajcd

Есть ли другой способ? Одним из них является удаление и повторная вставка ключа с новым значением, которое выводит acdj в качестве вывода. В моем случае я хочу сделать это для нескольких ключей на основе некоторого свойства объекта, используемого в качестве значения?

Было бы предпочтительнее использовать потоки.

Ответы [ 4 ]

2 голосов
/ 21 июня 2019

Этот связанный список определяет порядок итераций, который обычно является порядком, в котором ключи были вставлены в карту (порядок вставки). Обратите внимание, что порядок вставки не изменяется, если ключ повторно вставлен в карту

Javadoc LinkedHashMap .

отслеживает вставку ключей , и если мы добавим Map.put javadoc:

Если карта ранее содержала сопоставление для ключа, старое значение заменяется указанным значением.

Карта Javadoc

Entry не является заменой, изменяется только значение, поэтому key остается прежним.

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

0 голосов
/ 21 июня 2019

Если я правильно понимаю, вы хотите переназначить все пары ключ-значение, для которых значение равно определенному свойству, например, "a", и сделать это с помощью потоков.

Вот решение. Сначала выберите все записи карты, которые соответствуют вашему критерию, затем для каждой из них удалите и повторно вставьте запись в карту.

String criterion = "a"; // For example
map.entrySet().stream()
    .filter(e -> e.getValue().equals(criterion))
    .collect(Collectors.toList())
    .forEach(e -> { map.remove(e.getKey()); map.put(e.getKey(), e.getValue()); } );

Например, если у вас есть:

a=a
b=b
c=c 
d=d
e=a

Вы получите:

b=b
c=c
d=d
a=a
e=a
0 голосов
/ 21 июня 2019

Вставка хеш-карты основана только на хеш-коде. Например, ключ "b" имеет хеш-код 98.

для map.put ("b", "b");

Вы вставляете в качестве ключа "b", который имеет код 98. так будет выглядеть. 98 ---> содержит значение 'b'.

еще раз, если вы попытаетесь поставить на тот же ключ "b", который имеет только хеш-код 98. поэтому hashmap пытается связать только с тем же хеш-кодом, который 98 ---> содержит в качестве значения "j".

чтобы узнать, как работает хэш-код, проверьте ссылку ниже https://www.geeksforgeeks.org/internal-working-of-hashmap-java/

0 голосов
/ 21 июня 2019

HashMap не сортируется ни по ключам, ни по значениям.То, что вы ищете, это TreeMap.Для HashMap единственной гарантией является то, что ключи хешируются и помещаются в массив на основе их хеш-функции.

LinkedHashMap, в соответствии с Javadoc, создает внутренний LinkedList и отслеживает исходный порядок вставкизаписей.Другими словами, если вы используете LinkedHashMap, вы вообще не будете получать «отсортированный» список.

У вас есть два варианта решения этой проблемы: либо используйте TreeMap (или его производную), либосортировать каждый раз, когда вы хотите вывести значения.TreeMaps имеют внутреннюю сортировку, основанную на их ключах.Если ключи сравниваются друг с другом так, как вы ожидаете (сравнивая строки), то вы получаете правильную сортировку по возрастанию на основе ключей.Однако это не решит вашу проблему, так как вы хотите отсортировать значения.

Чтобы решить исходную проблему, используйте двунаправленную TreeMap.Apache Commons4 реализует такую ​​карту (https://commons.apache.org/proper/commons-collections/javadocs/api-4.3/org/apache/commons/collections4/bidimap/AbstractDualBidiMap.html#values--). Она позволяет вам получить доступ как к ключу, так и к набору значений. Но учтите, что эта карта не будет работать для вас, если ваши значения не уникальны Как и ключи, все значения в двунаправленной карте должны быть уникальными, поскольку они сами должны служить в качестве ключей.

Из Javadoc:

Эта карта применяет ограничение, которое существуетэто соотношение 1: 1 между ключами и значениями, означающее, что несколько ключей не могут отображаться на одно и то же значение. Это необходимо для того, чтобы «инвертировать» карту приводило к карте без дубликатов ключей. См. описание метода put (K, V)для получения дополнительной информации.

...