Is it possible to create Kotlin `Map` where key is...
# announcements
k
Is it possible to create Kotlin
Map
where key is
String
and case insensitive?
a
If anything, you might just want to process it before like
mapName[keyName.toLowerCase()]
or something
☝️ 1
a
Maybe make your own Map doing that preprocessing
s
You could also create you own key type:
Copy code
class LowerCase(val value: String) {
  // write your own equals and hashCode to make it case insensitive
}
and have some nice toplevel or extension function to create a LowerCase from a String
👍 1
d
Just wrap the String into a data class that extends from Comparator and then implement the compators
k
Comparator
? That's not really necessary here, right?
k
The thing is, AWS does some magic when mapping requests to the open class request contract. Can’t find a way to intervene that process. Going to check key type @streetsofboston – looks promising
f
On Android be very careful with toLowerCase(). It'll use the default locale and on e.g. Turkish devices the
i
will be replaced with
ı
.
d
Sorry I had a lapsus, it is enough with hashCode and Equeals
k
Copy code
data class HeaderName(val key: String) {

    override fun hashCode() = key.toLowerCase().hashCode()

    override fun equals(other: Any?): Boolean {
        return this.hashCode() == other.hashCode()
    }
}
Looks good?
k
No! Hashes aren't unique!
Also now you're using the default locale instead of a fixed one.
a
I mean, depending on the use, they could be unique enough, right?
k
And you don't do type checking in
equals
at all, there's a bunch of stuff you need to check there.
k
Now I’m really confused. I opened REPL and made to strings that are similar, and did hashCode(), they are the same.
k
@amanda.hinchman-dominguez Depending on hashcodes of strings being distinct is a terrible idea, there are lots of 3-letter collision examples.
What you have now will always say equal strings are equal, but there are also non-equal things that it's going to say are equal.
k
god damnit, that’s definitely not good
a
Yeah, to @karelpeeters point, I'm not sure why there are unique keys being made if they're not case sensitive
k
I think this is correct:
Copy code
class HeaderName(val key: String) {
	override fun hashCode() = key.toLowerCase(Locale.ROOT).hashCode()

	override fun equals(other: Any?): Boolean {
		if (this === other) return true
		if (javaClass != other?.javaClass) return false
		other as HeaderName
		
		return key.toLowerCase(Locale.ROOT) == other.key.toLowerCase(Locale.ROOT)
	}
}
You can also keep the
toLowerCase
result:
Copy code
class HeaderName(key: String) {
	val key = key.toLowerCase(Locale.ROOT)
	
	override fun hashCode() = key.hashCode()

	override fun equals(other: Any?): Boolean {
		if (this === other) return true
		if (javaClass != other?.javaClass) return false
		other as HeaderName

		return key == other.key
	}
}
k
Thanks, that’s definitely more strict