【问题标题】:How to use ConcurrentHashMap computeIfAbsent() in Scala如何在 Scala 中使用 ConcurrentHashMap computeIfAbsent()
【发布时间】:2016-04-24 18:53:36
【问题描述】:

我在 Scala 中使用 ConcurrentHashMap,我想使用 computeIfAbsent() 方法,但无法弄清楚第二个参数的语法。有人可以告诉我什么是正确的语法吗?

运行以下代码时

val data = new ConcurrentHashMap[String, LongAdder]

data.computeIfAbsent("bob", k: String => new LongAdder()).increment()

我收到以下错误

Type mismatch, expected: Function[_ >: String, _ <: LongAdder], actual: (String) => Any

提前谢谢你

弗朗西斯

【问题讨论】:

    标签: scala concurrenthashmap


    【解决方案1】:

    问题在于您使用的是java.util.concurrent.ConcurrentHashMap,它接受java.util.function.Function 作为computeIfAbsent() 的参数,而不是您传递给它的scala.Function1

    由于 scala 不像 Java 那样支持函数式接口的 lambda 转换(至少在没有 -Xexperimental flag 的情况下不支持),您可以通过显式实现 java.util.function.Function 来解决这个问题:

    val data = new ConcurrentHashMap[String, LongAdder]
    val adderSupplier = new java.util.function.Function[String, LongAdder]() {
      override def apply(t: String): LongAdder = new LongAdder()
    }
    data.computeIfAbsent("bob", adderSupplier).increment()
    

    或者,如果您更频繁地需要这个,您可以编写一个实用转换函数,甚至是一个隐式转换:

    object FunctionConverter {
      implicit def scalaFunctionToJava[From, To](function: (From) => To): java.util.function.Function[From, To] = {
        new java.util.function.Function[From, To] {
          override def apply(input: From): To = function(input)
        }
      }
    }
    
    import FunctionConverter._
    val data = new ConcurrentHashMap[String, LongAdder]()
    data.computeIfAbsent("bob", (k: String) => new LongAdder()) // <- implicit conversion applied here
    

    【讨论】:

      【解决方案2】:

      如果启用 -Xexperimental 标志,您可以为此使用 scala 匿名函数表示法:

      scala> val data = new java.util.concurrent.ConcurrentHashMap[String, Int]
      data: java.util.concurrent.ConcurrentHashMap[String,Int] = {}
      
      scala> data.computeIfAbsent("bob", _.size)
      res0: Int = 3
      

      请注意,您仍然无法通过常规 scala Function

      scala> val f: String => Int = _.size
      f: String => Int = <function1>
      
      scala> data.computeIfAbsent("bob", f)
      <console>:13: error: type mismatch;
       found   : String => Int
       required: java.util.function.Function[_ >: String, _ <: Int]
             data.computeIfAbsent("bob", f)
                                     ^
      

      但是 eta-expansion 会起作用

      scala> def a(s: String): Int = s.size
      a: (s: String)Int
      
      scala> data.computeIfAbsent("bob", a)
      res3: Int = 3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-03
        • 2013-10-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多