Imagine a following interface:
interface IConnectionManager {
fun connect(connection: Int)
fun disconnect(connection: Int)
fun disconnectAll()
}
Simple implementation might look like this:
class ConnectionManager: IConnectionManager {
private val connections = mutableMapOf<Int, String>()
override fun connect(connection: Int) {
connections[connection] = "Connection $connection"
}
override fun disconnect(connection: Int) {
connections.remove(connection)?.let {
println("Closing connection $it")
}
}
override fun disconnectAll() {
connections.forEach {
disconnect(it.key)
}
}
}
Now you probably see the problem. Whenever I call disconnectAll(), I get ConcurrentModificationException.
And I know and understand why (iterators). But I can't figure a way how to implement those disconnect() and disconnectAll() methods.
I have some ideas, some of them even works, but they are ugly, and might cause bugs elsewhere:
- In
disconnectAll()make copy ofconnections.keysand use this. This works, but might obviously cause problem when some other thread desiced to add new connection. - Pass iterator object from
disconnectAll()to newdisconnect(iterator). Seems just ugly, and causes code duplication and I couldn't make it to works. - Make
private closeConnection(connection: Int)which wil not remove the connection from collection, and call it from bothdisconnect()anddisconnectAll()functions. This might actualy be the best solution, but I didn't tried it yet.
Or is there some other, more elegant Kotlin solution?