Enum Reverse Lookup in Kotlin

Enum Reverse Lookup in Kotlin

Problem

Kotlin bietet die Möglichkeit, einem Aufzählungstypen Aufzählungswerte zuzuweisen:

enum class Currency(val symbol: String) {
    DOLLAR("$"),
    EURO("€"),
    POUND("£");

    override fun toString(): String {return this.symbol}
}
So kann durch Auswahl des Aufzählungstyps dessen Wert zurückgegeben werden:
Currency.valueOf("DOLLAR") // returns the enumeration value “$”
Möchte man aber ausgehend von einem Wert auf den entsprechenden Eintrag schließen, bietet Kotlin dafür keine native Funktion an. Man muss also über alle Aufzählungstypen iterieren und jeweils den Wert mit dem gesuchten Wert vergleichen:
Currency.values().firstOrNull {currency -> currency.symbol == "$"} // returns the enumeration type DOLLAR

Diese Art von Lösung findet sich im Netz in der einen oder anderen Variante und sie tut, was sie soll. Aber möchte man jedes Mal über alle Aufzählungen iterieren und Werte vergleichen? Gibt es dafür keine elegantere Lösung?

Lösung

Wir erweitern unsere Aufzählungsklasse mit einem Companion Object:

companion object {
    private val mapping = values().associateBy(Currency::symbol)
    fun fromSymbol(symbol: String) = mapping[symbol]
 }

Die Funktion associateBy() liefert eine Map<K, T> zurück. Genauer eine LinkedHashMap bei der K der Aufzählungswert und T unser Aufzählungstyp ist. Die Funktion "fromSymbol()" nimmt den Aufzählungswert als Argument entgegen und liefert uns den passenden Aufzählungstyp. Der Zugriff auf den Aufzählungstyp über den Aufzählungswert erfolgt jetzt nicht mehr durch iterieren in O(n), sondern über einen Hash Lookup in der statischen Map in O(1).

Mit dieser Erweiterung kann der Reverse Lookup folgendermaßen durchgeführt werden:

Currency.fromSymbol("$") // returns the enumeration type DOLLAR

Damit haben wir eine Lösung mit leichter lesbarem Code, die u. U. sogar performanter bzgl. der Ausführungszeit sein kann.

Vorsicht: Wenn es keine 1 zu 1 Beziehung zwischen Aufzählungstypen und Aufzählungswerten gibt, liefert diese Lösung nicht den ersten Treffer, sondern den letzten Treffer.

Cookie-Einstellungen

Diese Website verwendet Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und Zugriffe auf die Website zu analysieren. Zudem werden Informationen zu Ihrer Verwendung der Website an Partner für soziale Medien, Werbung und Analysen weitergegeben. Die Partner führen diese Informationen möglicherweise mit weiteren Daten zusammen, die Sie ihnen bereitgestellt haben oder die sie im Rahmen Ihrer Nutzung der Dienste gesammelt haben.

Weitere Informationen finden Sie in unserer Datenschutzerklärung. Dort können Sie nachträglich auch Ihre Cookie-Einstellungen ändern.

contact icon

Kontakt aufnehmen