Reputation: 5733
I have the following test application. My aim is the change all keys in SortMap.
With this code at bottom I get a java.util.ConcurrentModificationException
.
My question now would be how to do this. I thought that with iterator it would work fine.
public TestClass() {
final SortedMap<String, String> sm = new TreeMap<>();
sm.put("1", "one");
sm.put("2", "two");
sm.put("3", "three");
sm.put("4", "four");
sm.put("5", "five");
System.out.println(sm);
for (final Iterator<String> iterator = sm.keySet().iterator(); iterator.hasNext();) {
final String next = iterator.next();
sm.put(next + "-shifted", sm.remove(next));
}
System.out.println(sm);
}
public static void main(String[] args) {
new TestClass();
}
Upvotes: 1
Views: 49
Reputation: 137084
You are getting a ConcurrentModificationException
because you are not using iterator
remove method in the following line:
sm.put(next + "-shifted", sm.remove(next)); // <-- does not call iterator.remove but sm.remove
You won't be able to update the existing Map in place but you can create a new Map holding the result instead of modifying the existing one. For that, you can do collect all the entries of the existing Map into a new TreeMap
:
SortedMap<String, String> changed =
sm.entrySet()
.stream()
.collect(toMap(
e -> e.getKey() + "-shifted",
Map.Entry::getValue,
(v1, v2) -> { throw new IllegalStateException(); },
TreeMap::new)
));
Upvotes: 1
Reputation: 24
try this:
final SortedMap<String, String> sm = new TreeMap<String, String>();
sm.put("1", "one");
sm.put("2", "two");
sm.put("3", "three");
sm.put("4", "four");
sm.put("5", "five");
System.out.println(sm);
final Object[] arrayKeys = sm.keySet().toArray();
for (int i = 0; i < arrayKeys.length; i++) {
sm.put(arrayKeys[i] + "-shifted", sm.remove(arrayKeys[i]));
}
System.out.println(sm);
Upvotes: 0
Reputation: 93842
The problem is that you are adding and removing elements at the same time while iterating (and you're not removing via the iterator either).
AFAIK, there's no way to replace the keys in place so I think your simplest option is to build a new map with the entries of sm
.
final SortedMap<String, String> sm2 =
sm.entrySet()
.stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey() + "-shifted", e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> {throw new IllegalStateException();},
TreeMap::new));
Upvotes: 2