1

我有以下情况:

Java库类:

class LibClass {
  ArrayList<LibClass> children;
}

我的程序 Scala 代码:

abstract class MyClass extends LibClass {
  def boom { }
  def boomMyClassInstances  // ???
}

class Lala extends MyClass
class Hoho extends MyClass

问题是:在方法boomMyClassInstances中,获取所有 的最 Scala-ish 方法是什么childrenMyClass存储在 中,children ArrayList以便我可以boom对它们调用通用方法?

我的尝试是:

def boomMyClassInstances {
  children.toArray.map { case mc: MyClass => mc.boom }
}

这是一个正确的方法吗?它会选择所有的孩子,MyClass这是正确的 Scala 方式,还是我必须说一些关于类型边界的事情?

4

4 回答 4

5
import collection.JavaConverters._

children.asScala.foreach { 
  case mc: MyClass => mc.boom 
  case _ => ()
}
于 2012-07-02T11:57:54.073 回答
4

退房GenTraversableLike.collect。它的签名本质上是Traversable[A].collect[B <: A](f: A ~> B): Traversable[B],也就是说,它接受一个包含类型元素的集合A和一个to的函数f,并返回一个静态元素类型的集合,其中是 的一个子类型。ABBBA

val myClassInstances: List[MyClass] =
  children.toList.collect{case mc: MyClass => mc}

由于map需要一个总函数,因此您上面的尝试将失败,scala.MatchError以防万一children不仅包含MyClass. 您可以使用Optionor来解决这个问题flatMap,但这collect似乎是实现您想要的最 Scala-ish 的方式。

于 2012-07-02T11:55:54.050 回答
2

我不是类型专家,所以我不能肯定地说你的解决方案会起作用,但它似乎确实应该起作用。它的优点是直截了当,这总是好的。

不过,您确实需要添加一个包罗万象的案例(以免得到 a scala.MatchError)。

case _ => // do nothing
于 2012-07-02T11:58:25.917 回答
1

您想要collect相关部分:

children.iterator collect { case mc: MyClass => mc } foreach (_.boom())
于 2012-07-02T13:19:32.110 回答