我有一个 JSONObject,如果映射中存在值,我需要重命名一些键。这会不断抛出 ConcurrentModificationException。有什么方法可以实现这一点而不是经历多个循环?
JSONObject jsonObject = new JSONObject(result);
jsonObject.keySet().stream().forEach(key -> {
if (someMap.containsKey(key)) {
jsonObject.put(someMap.get(key), jsonObject.get(key)); //Update the key in jsonObject with same value
jsonObject.remove(key);
}
});
最佳答案
documentation对于 ConcurrentModificationException
解释了这一点:
If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
从 someMap
开始处理您的问题,您不必同时修改,因此会抛出异常。
解决方案可能是:
someMap.entrySet()
.stream()
.filter(entry -> jsonObject.has(entry.getKey()))
.forEach(entry -> {
jsonObject.put(entry.getKey(), entry.getValue());
jsonObject.remove(entry.getKey());
});
我不太明白为什么你要先 put()
然后 remove()
但话又说回来,这对于解决方案来说并不是必需的。
我假设您正在通过您正在使用的方法使用 JSON-lib,因此您也可以收集到 map :
someMap.entrySet()
.stream()
.filter(entry -> jsonObject.has(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
JSONObject 有一个 putAll(Map map) 来快速完成此工作。
接下来就需要对适合您的方法进行基准测试了。
关于java - 更新 JSONObject 时发生并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51737373/