我有以下情况:
Java lib类:
class LibClass {
ArrayList<LibClass> children;
}
我的程序Scala代码:
abstract class MyClass extends LibClass {
def boom { }
def boomMyClassInstances // ???
}
class Lala extends MyClass
class Hoho extends MyClass
问题是:在boomMyClassInstances
方法中,获取children
MyClass
的所有children
的最常见Scala-ish方式是什么,存储在ArrayList
{{1}所以我可以在它们上面调用常见的boom
方法吗?
我的尝试是:
def boomMyClassInstances {
children.toArray.map { case mc: MyClass => mc.boom }
}
这是正确的做法吗?它会选择MyClass
的所有子项,这是正确的Scala方式,还是我必须说一下类型边界?
答案 0 :(得分:5)
import collection.JavaConverters._
children.asScala.foreach {
case mc: MyClass => mc.boom
case _ => ()
}
答案 1 :(得分:4)
结帐GenTraversableLike.collect
。它的签名基本上是Traversable[A].collect[B <: A](f: A ~> B): Traversable[B]
,也就是说,它从A
到{需要一个类型为f
的元素和一个部分函数A
的集合{1}},并返回静态元素类型B
的集合,其中B
是B
的子类型。
A
由于val myClassInstances: List[MyClass] =
children.toList.collect{case mc: MyClass => mc}
需要一个完整的功能,如果map
scala.MatchError
不仅包含children
的实例,则上述尝试将失败并显示MyClass
。您可以使用Option
或flatMap
解决此问题,但collect
似乎是实现您想要的最多Scala-ish方式。
答案 2 :(得分:2)
我不是类型专家,所以我不能肯定地说你的解决方案会起作用,但看起来确实应该有效。它具有直截了当的优点,总是很好。
你确实需要添加一个包罗万象的案例(以便得不到scala.MatchError
)。
case _ => // do nothing
答案 3 :(得分:1)
您希望collect
相关部分:
children.iterator collect { case mc: MyClass => mc } foreach (_.boom())