交换Guava MutableValueGraph中的节点

我正在试图替换com.google.common.graph.MutableValueGraph的元素。

我需要在以下数据类中更新元素状态(我知道文档建议要小心):

 data class Frame(val method: String, val merged: Boolean = false) 

由于图形没有提供交换节点的方法,所以我翻译了自己的:

 fun MutableValueGraph<Frame, Int>.exchangeNode(old: Frame, new: Frame): Boolean { if (old == new) return true if (isDirected) { this.predecessors(old).forEach { this.putEdgeValue(it, new, this.edgeValue(it, old)) } this.successors(old).forEach { this.putEdgeValue(new, it, this.edgeValue(old, it)) } } else { this.adjacentNodes(old).forEach { this.putEdgeValue(it, new, this.edgeValue(it, old)) } } return this.removeNode(old) } 

但是,我碰到一个ConcurrentModificationException:

 Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437) at java.util.HashMap$EntryIterator.next(HashMap.java:1471) at java.util.HashMap$EntryIterator.next(HashMap.java:1469) at com.google.common.graph.DirectedGraphConnections$1$1.computeNext(DirectedGraphConnections.java:113) at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:145) at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:140) at TestKt.exchangeNode(Test.kt:292) ... 

听起来很公平,因为我在一个for循环中交换了一堆节点,可能试图触摸已经交换的相邻节点?

我的问题是:我如何替换ValueGraph中的多个节点,保持其边缘值?

效率较低的方法,但是一定要避免ConcurrentModificationException是从相关节点引发一个子图,然后删除旧节点并添加新的,最后使用诱导子图将边值添加回来:

 fun MutableValueGraph<Frame, Int>.exchangeNode(old: Frame, new: Frame): Boolean { if (old == new) return false val inducedSubgraph = Graphs.inducedSubgraph(this, adjacentNodes(old) + old) removeNode(old) addNode(new) if (isDirected) { for (predecessor in inducedSubgraph.predecessors(old)) { putEdgeValue(predecessor, new, inducedSubgraph.edgeValue(predecessor, old)) } for (successor in inducedSubgraph.successors(old)) { putEdgeValue(new, successor, inducedSubgraph.edgeValue(old, successor)) } } else { for (adjacentNode in inducedSubgraph.adjacentNodes(old)) { putEdgeValue(adjacentNode, new, inducedSubgraph.edgeValue(adjacentNode, old)) } } return true }