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.keys
and 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?