hashmap kotlin的不区分大小写的键?

时间:2021-04-22 10:31:04

标签: kotlin hashmap

我有一个哈希图,以字符串为键,以整数为值。我希望键不区分大小写。

val items = HashMap<String, Int>()
    items["key1"] = 90
    items["Key1"] = 80
    items["C"] = 70
    for ((k, v) in items) {
        println("$k = $v")
    }

这将 key1 和 Key1 作为单独的条目

3 个答案:

答案 0 :(得分:4)

为此,您需要提供一些扩展函数,以某种定义的方式放置和获取条目(例如使用 everytime toLowerCase() String 的方法)保持键不区分大小写

fun HashMap<String, Int>.putInsensitive(k: String, v: Int) {
    this[k.toLowerCase()] = v
}

fun HashMap<String, Int>.getInsensitive(k: String, v: Int): Int? = this[k.toLowerCase()]

或提供您自己的 Map 接口实现(它甚至可以从 HashMap 继承)

class InsensitiveHashMap<V> : HashMap<String, V>() {
    override fun put(key: String, value: V): V? {
        return super.put(key.toLowerCase(), value)
    }

    override fun get(key: String): V? {
        return super.get(key.toLowerCase())
    }
}

答案 1 :(得分:2)

尽管您可以使用 HashMap 的扩展来伪造它(如另一个答案中所述),但我认为这不是一个好的解决方案:为了使地图的行为完全一致,您可能需要覆盖很多方法。 (例如,如果您通过 keySet 更新地图,将很难确保它保持不区分大小写。 并且可能还有更多问题。)

在大多数情况下,您并不真正需要专门的 HashMap — 您只需要一个 Map 实现。因此,另一种选择是使用另一种类型的地图,让您提供自己的Comparator,例如:

val items = TreeMap<String, Int>{ a, b -> 
    a.toLowerCase().compareTo(b.toLowerCase())
}

TreeMapSortedMap 的一种实现——一种特殊类型的 Map,它保持其键的顺序:要么是它们的自然顺序,要么是您提供的顺序。在本例中,我给出了一个简单的 Comparator 实现,用于比较两个字符串的小写版本。

有了这个定义,问题中的其余代码运行良好,并打印出来:

C = 70
key1 = 80

...即它已经认识到“Key1”应该被视为与“key1”相同,并更新该值而不是添加一个新值。我认为这是您想要的行为。

您不需要考虑地图已排序的事实;这只是一个额外的好处。您仍然可以像对待任何其他 Map 实现一样对待它,一切都应该可以正常工作。

(这是另一个例子,说明为什么最好对接口进行编程,而不是实现。 如果您编写的代码可以使用任何 Map 实现,您可以给它一个 HashMapTreeMap 或任何其他类型的地图,无需任何更改。)

答案 2 :(得分:0)

@m.antkowicz 的答案的变体,您实际上可以“覆盖”HashMap 本身的 get/put 运算符(并使其成为一个很棒的足球):


operator fun HashMap<String, Int>.get(k: String): Int? = this[k.toLowerCase()]
operator fun HashMap<String, Int>.set(k: String, v: Int): Int? {
    val originalK = this[k.toLowerCase()]
    this.put(k.toLowerCase(), v )
    return originalK
}

现在您可以:


fun main() {
    val items = HashMap<String, Int>()
    items["key1"] = 90
    items["Key1"] = 80
    items["C"] = 70

    for ((k, v) in items) {
        println("$k = $v")
    }
// Prints:
//    key1 = 80
//    c = 70
}
相关问题