quma
quma

Reputation: 5733

Java SortMap change keys

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

Answers (3)

Tunaki
Tunaki

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

diegoyucra
diegoyucra

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

Alexis C.
Alexis C.

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

Related Questions