【问题标题】:Lambda confusion in Kotlin, it == x vs equals(x)Kotlin 中的 Lambda 混淆,它 == x vs equals(x)
【发布时间】:2020-02-03 19:26:00
【问题描述】:

我正在做一个简单的测试,以了解我的代码为什么不起作用。

    val v = listOf("1", "2", "2", "3")
    assertThat((v.filter { equals("2") }).size , `is`(2))

失败,原因是“大小为 0”

但是当我将其更改为:

    val v = listOf("1", "2", "2", "3")
    assertThat((v.filter { it == "2" }).size , `is`(2))

在 Java 中我可以做到:

.filter(Objects::equals)

它返回预期的结果。任何人都可以理解为什么会出现这种行为???

【问题讨论】:

  • 当您在过滤器中调用equals("2") 时,它实际上调用的是this.equals("2")。这应该清楚为什么它不能按预期工作。请注意,有些scope functions 的对象引用是this 而不是it。在这种情况下,equals("2") 代码会起作用。但在filter() 的情况下,对象的作用域为it
  • @Jordan 谢谢你,现在我明白了,我真傻!这是关于范围
  • Kotlin 采取了正确的步骤来强制进行显式转换。但是隐式接收器已经成为许多新程序员都在努力解决的另一个问题......

标签: java kotlin lambda equals


【解决方案1】:

你需要写的是

    assertThat((v.filter { it.equals("2") }).size , `is`(2))

但请注意,如果您启用了“可以用二元运算符替换”检查,IntelliJ 会立即建议将 equals 调用替换为 ==

另外,不,您不能在 Java 中将此特定调用编写为 .filter(Objects::equals),因为静态 Objects#equals 采用 2 个参数,而方法 filter 仅为其 lambda 参数提供 1 个参数。但是您仍然可以在 Kotlin 中使用函数引用(期望 lambda 具有适当的函数)。例如,您可以像这样过滤所有非空字符串:

    val v = listOf("1", "", "2", "   ", "\t", "3")
    println(v.filter(String::isNotBlank))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 2013-03-03
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    相关资源
    最近更新 更多