java Kotlin:保留、替换或删除每个Map条目

8yoxcaq7  于 2023-01-16  发布在  Java
关注(0)|答案(4)|浏览(241)

我在Kotlin中有一个可变Map(具体来说是LinkedHashMap),对于每个Map条目,我想有条件地执行以下三个操作之一:

  • 按原样保留条目
  • 替换条目的值
  • 删除条目

在旧的Java中,我可能会使用Iterator而不是map的entrySet()来实现这个目的(相应地使用Iterator.remove()Entry.setValue()),但是,我想知道Kotlin中是否存在一种更优雅的、函数式的方法来实现同样的目的(即将lambda应用于每个条目,类似于使用replaceAll(),但也具有删除条目的能力)。
在Kotlin中,replaceAll()retainAll()的以下组合执行相同的操作:

val map = LinkedHashMap<String,Int>(mapOf("a" to 1, "b" to 2, "c" to 3))
map.replaceAll { key, value ->
    if(key.startsWith("a")) {
        value * 2
    } else {
        value
    }
}
map.entries.retainAll { entry ->
    entry.key.startsWith("a") || entry.key.startsWith("b")
}

然而,这会迭代Map两次,并且需要拆分 predicate /转换。我更喜欢compute()风格的一体化解决方案,只针对所有条目。

pdsfdshx

pdsfdshx1#

以下是如何在单个表达式中执行所有运算的示例:

  • 使用filter{},我们只保留符合特定条件的元素,如下所示:值〉= 200。此过滤器的结果是新贴图。
  • 使用map,我们将上一步中的map转换为一个新的集合。转换时,我们改变一些值,一些保持不变。
  • 使用toMap(),我们将生成的集合转换为一个新的Map。
fun main(args: Array<String>) {
    val map = mutableMapOf<String, Int>()

    map.put("a1", 101)
    map.put("a2", 102)

    map.put("b1", 201)
    map.put("b2", 202)

    map.put("c1", 301)
    map.put("c2", 302)

    println(map)

    val result = map.filter { (key, value) -> value >= 200 }.
        map { (key,value) -> 
                if (value >= 300)   Pair(key, value * 100) 
                else                Pair(key, value)
    }.toMap()

    println(result)
}
c90pui9n

c90pui9n2#

在函数世界中,不变性是一个基本原则,因此原地修改是不方便的。
但是如果你更喜欢原地替换的方法,可以选择retainAllremoveAll来过滤项,对于原地替换,你需要迭代集合,你可以使用forEach来做原地修改:

data class User(var name: String)

val users = mutableListOf( User("John"), User("Alice"), User("Bob") )
users.run {
    removeAll { it.name == "Alice" }
    forEach { it.name =  "Mr. ${it.name}"}
}
biswetbf

biswetbf3#

例如,你可以这样写

fun main() {
    val map = mapOf(
        "test1" to 1,
        "test2" to 2,
        "test3" to 3
    )
    val resultMap = map.mapNotNull { (key, value) ->
        when (value) {
            1 -> null // remove
            2 -> key to 4 // replace
            else -> key to value // retain
        }
    }.toMap()
    println(resultMap) // print {test2=4, test3=3}
}
1tuwyuhd

1tuwyuhd4#

这个版本已经准备好了(类似于你用java写的东西),但是没有使用函数方法

val map: MutableMap<String, Int> = mutableMapOf(
    ("a" to 1),
    ("b" to 2),
    ("c" to 3),
)

val mapIterator = map.iterator()
while (mapIterator.hasNext()) {
    val mapEntry = mapIterator.next()

    when (mapEntry.key) {
        "a" -> mapIterator.remove()
        "c" -> mapEntry.setValue(mapEntry.value * 2)
        else -> println("retain this  entry")
    }
}

相关问题