在LinkedHashMap中结合remove和put方法

时间:2019-06-21 05:21:26

标签: java java-8 java-stream linkedhashmap

使用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 个答案:

答案 0 :(得分:2)

  

此链接列表定义了迭代顺序,通常是将键插入映射中的顺序(插入顺序)。请注意,如果将密钥重新插入到地图中,则插入顺序不会受到影响

LinkedHashMap javadoc

它会跟踪 keys 插入,以及是否添加了Map.put javadoc:

  

如果映射先前包含键的映射,则旧值将替换为指定值。

Map javadoc

Entry不会被替换,只会修改值,因此key保持不变。

您需要删除然后插入该值以更新键的顺序。

答案 1 :(得分:0)

HashMap既不按键也不按值排序。您正在寻找的是TreeMap。 对于HashMap,唯一的保证是,根据键的哈希值对键进行哈希处理并将其放入数组中。

根据Javadoc,LinkedHashMap创建一个内部LinkedList,并跟踪条目的原始插入顺序。换句话说,如果您使用LinkedHashMap,则根本不会收到“已排序”列表。

有两种方法可以解决此问题:使用TreeMap(或其派生类),或者每次要输出值时都进行排序。 TreeMap基于其键进行内部排序。如果将键以您期望的方式相互比较(通过比较字符串),则您将根据键获得正确的升序排序。但是,这并不能解决您要对值进行排序的问题。

要解决您的原始问题,请使用双向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)方法说明。

答案 2 :(得分:0)

如果我理解正确,您想重新映射其值等于已定义属性(例如“ 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

答案 3 :(得分:-2)

哈希图插入仅基于哈希码。例如,键“ b”的哈希码为98。

对于map.put(“ b”,“ b”);

您插入具有代码98的键“ b”。 所以看起来像98 --->保留值“ b”。

再次

,如果您尝试插入仅具有哈希码98的相同键“ b”。 因此,哈希映射仅尝试链接到相同的哈希码,即98 --->将“ j”作为值。

有关哈希图哈希码的已知工作,请查看以下链接 https://www.geeksforgeeks.org/internal-working-of-hashmap-java/