如何在 Scala 中使用 ConcurrentHashMap computeIfAbsent()
How to use ConcurrentHashMap computeIfAbsent() in Scala
我在 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
提前致谢
弗朗西斯
问题是您使用的是 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
如果您启用 -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 扩展会起作用
scala> def a(s: String): Int = s.size
a: (s: String)Int
scala> data.computeIfAbsent("bob", a)
res3: Int = 3
我在 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
提前致谢
弗朗西斯
问题是您使用的是 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
如果您启用 -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 扩展会起作用
scala> def a(s: String): Int = s.size
a: (s: String)Int
scala> data.computeIfAbsent("bob", a)
res3: Int = 3