在处理问题陈述时,我需要访问Entry
中的下一个Map
,并且根据条件,我需要修改下一个条目值。
我一直在考虑这里提供的解决方案:How to get the previous key/value and the next key/value in Maps,在这里我可以使用higherEntry
访问NavigableMap
,但是它抛出:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractMap$SimpleImmutableEntry.setValue(AbstractMap.java:797)
这是完全理解的。这是代码段
for (Map.Entry<Character, Integer> current : myMap.entrySet()) {
Map.Entry<Character, Integer> next = myMap.higherEntry(current.getKey());
if (current.getValue() == next.getValue()) {
// Code block
} else if (current.getValue() > next.getValue()) {
// Code block
} else {
next.setValue(1); // Line that throws Exception
}
}
如何在需要时遍历Map
,访问和修改下一个条目?
答案 0 :(得分:0)
您可以使用普通的for循环而不用使用增强的for循环并跟踪索引。这很棘手,因为您需要一种访问下一个条目的方法,这取决于您是否使用Map
的有序实现(例如LinkedHashMap
)。如果您未使用LinkedHashMap
或某些类似的有序映射,则这将不一致,并且条目可能会混乱。假设您使用的是有序映射,则可以先将条目集转换为数组,然后从该数组开始。看起来像Map.Entry<Character, Integer>[] entries = myMap.entrySet().stream().toArray(Map.Entry[]::new);
,然后,您可以将此数组与for循环一起使用。
for (int i = 0; i < entries.length-1; i++) {
Map.Entry<Character, Integer> current = entries[i];
Map.Entry<Character, Integer> next = entries[i+1];
//code that does stuff
}
答案 1 :(得分:0)
TreeMap.higherEntry
返回一个不可变条目,它解释了您所看到的UnsupportedOperationException
:
//exportEntry is being called by TreeMap.higherEntry(K)
static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
return (e == null) ? null :
new AbstractMap.SimpleImmutableEntry<>(e);
}
一种可能的解决方案/解决方法是将更新的条目收集到地图中,然后在循环之后修改原始地图:
Map<Character, Integer> updates = new HashMap<>();
for (Map.Entry<Character, Integer> current : myMap.entrySet()) {
Map.Entry<Character, Integer> next = myMap.higherEntry(current.getKey());
if(null != next) {
if (current.getValue() == next.getValue()) {
} else if (current.getValue() > next.getValue()) {
} else {
updates.put(next.getKey(), 1); // entry to be updated
}
}
}
myMap.putAll(updates);
请注意,由于myMap.higherEntry
可能返回null
,因此我添加了空检查。
答案 2 :(得分:0)
Map.Entry<String, Integer> next = myMap.higherEntry(current.getKey());
if(next != null)
{
if (current.getValue() == next.getValue())
{
//Code block
}
else if (current.getValue() > next.getValue()) {
//Code block
}
else {
myMap.put(current.getKey(), 1);
}
}
答案 3 :(得分:0)
方法higherEntry
返回一个不可变的条目,但是您的代码也缺少对没有更高条目的情况的处理。另一方面,迭代器返回的下一个条目无论如何都是正确的条目(如果有的话),因此可以手动使用Iterator
来完成,如下所示:
Iterator<Map.Entry<Character, Integer>> it = myMap.entrySet().iterator();
if(it.hasNext()) {
for(Map.Entry<Character, Integer> current=it.next(), next; it.hasNext(); current=next) {
next = it.next();
// don't compare Integer objects via ==, use equals
if (current.getValue().equals(next.getValue())) {
// Code block
} else if (current.getValue() > next.getValue()) {
// Code block
} else {
next.setValue(1);
}
}
}
“不太干净”但相当简单的替代方法是
Map.Entry<Character, Integer> current = null;
for(Map.Entry<Character, Integer> next: myMap.entrySet()) {
if(current != null) {
if (current.getValue().equals(next.getValue())) {
// Code block
} else if (current.getValue() > next.getValue()) {
// Code block
} else {
next.setValue(1);
}
}
current = next;
}