我正在尝试从Java代码中调用我的Scala Util
对象:
Main.java
Set<Long> items = new HashSet<Long>();
// fill up items with Long
MyUtil.foo(100, items);
Util.scala
object Foo {
type Id = Long
def foo(id: Id, items: scala.collection.mutable.Set[Id])
这是编译时错误:
could not parse error message:
required: long,scala.collection.mutable.Set<Object>
found: Long,java.util.Set<Long>
reason: actual argument java.util.Set<Long> cannot be converted to
scala.collection.mutable.Set<Object> by method invocation conversion`
从阅读这些Java到Scala Collections docs,我使用的是mutable
Set,而不是默认的,不可变的Set:
scala.collection.mutable.Set <=> java.util.Set
但是,我不明白错误信息。在我的Java代码中使用Long
(盒装long
),为什么找到了Set<Long>
?
答案 0 :(得分:2)
证明评论者所说的话:
scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> val js = (1 to 10).toSet.asJava
js: java.util.Set[Int] = [5, 10, 1, 6, 9, 2, 7, 3, 8, 4]
scala> def f(is: collection.mutable.Set[Int]) = is.size
f: (is: scala.collection.mutable.Set[Int])Int
scala> def g(js: java.util.Set[Int]) = f(js.asScala)
g: (js: java.util.Set[Int])Int
scala> g(js)
res0: Int = 10
答案 1 :(得分:1)
使用 Scala集合并从 Java代码中键入别名(而不是相反的,因为som-snytt显示:)将至少是令人讨厌的,大多数可能非常痛苦,而且很可能是不可能的。
如果您能够修改API的Scala端,我建议为其添加一个Java友好的API。如果没有,我猜你可以在Scala中构建一个适配器层,将Java客户端代理到本机Scala API。
所以,比如:
// Original Scala
object Foo {
type Id = Long
def foo(id: Id, items: scala.collection.mutable.Set[Id])
}
// Java adapter -- generics might be made to work on the Java side,
// but Long is particularly problematic, so we'll just force it here
object FooJ {
import scala.collection.JavaConverters._
def foo(id: Long, items: java.util.Set[Long]) = {
Foo.foo(id, items.asScala)
}
}