使用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
作为输出。在我的情况下,我想根据用作值的对象的某些属性对多个键进行此操作?
使用流的解决方案是更可取的。
答案 0 :(得分:2)
此链接列表定义了迭代顺序,通常是将键插入映射中的顺序(插入顺序)。请注意,如果将密钥重新插入到地图中,则插入顺序不会受到影响
它会跟踪 keys 插入,以及是否添加了Map.put
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/