commonMain.dk.cachet.carp.common.domain.ExtractUniqueKeyMap.kt Maven / Gradle / Ivy
Go to download
Helper classes and base types relied upon by all subsystems. This library does not contain any domain logic.
The newest version!
package dk.cachet.carp.common.domain
/**
* A [Map] which automatically extracts the key of added values and
* throws an error when attempting to add an element with a key which is already present.
*
* However, elements which have already been added (using referential equality checks) are ignored.
* Adding them again won't change the collection and does not throw an error.
*/
class ExtractUniqueKeyMap(
/**
* Specifies how to retrieve the key for the specified element.
*/
private val keyOf: (V) -> K,
/**
* Create error for the specified key which is already present while trying to add an element.
*/
private val keyPresentError: (K) -> Throwable
) : Map
{
private val map: MutableMap = mutableMapOf()
/**
* Associates the specified [element] with the key extracted from it and
* adds the key/value pair in case the key does not yet exist.
* Throws the exception created using [keyPresentError] when the key already exists.
*
* @return True if the element has been added; false if the specified element is already included in the map.
*/
fun tryAddIfKeyIsNew( element: V ): Boolean
{
val key = keyOf( element )
val storedElement: V? = map[ key ]
if ( storedElement != null )
{
if ( element === storedElement )
{
return false
}
throw keyPresentError( key )
}
map[ key ] = element
return true
}
/**
* Removes the specified [element] from this collection.
*
* @return True if the element has been removed; false if the specified element is not included in this collection.
*/
fun remove( element: V ): Boolean = map.remove( keyOf( element ) ) != null
/**
* Removes the element with the specified [key] from this collection.
*
* @return True if the element with [key] has been removed; false if no element with [key] is included in this collection.
*/
fun removeKey( key: K ): Boolean = map.remove( key ) != null
override val entries: Set> get() = map.entries
override val keys: Set get() = map.keys
override val size: Int get() = map.size
override val values: Collection get() = map.values
override fun containsKey( key: K ): Boolean = map.containsKey( key )
override fun containsValue( value: V ): Boolean = map.containsValue( value )
override fun get( key: K ): V? = map[ key ]
override fun isEmpty(): Boolean = map.isEmpty()
}