截至 2017 年,之前的答案似乎已经过时。我运行了一些基准测试(1000 万个 Ints 列表,第一个匹配大致在中间,Scala 2.12.3、Java 1.8.0、1.8 GHz Intel Core i5)。除非另有说明,list 和 map 具有以下类型:
list: scala.collection.immutable.List
map: A => Option[B]
只需调用列表中的map:~1000 毫秒
list.map(map).find(_.isDefined).flatten
第一次调用列表中的toStream:~1200 ms
list.toStream.map(map).find(_.isDefined).flatten
在列表中调用toStream.flatMap:~450 ms
list.toStream.flatMap(map(_).toList).headOption
在列表中调用flatMap:~100 毫秒
list.flatMap(map(_).toList).headOption
第一次调用列表中的iterator:~35 ms
list.iterator.map(map).find(_.isDefined).flatten
递归函数find():~25 ms
def find[A,B](list: scala.collection.immutable.List[A], map: A => Option[B]) : Option[B] = {
list match {
case Nil => None
case head::tail => map(head) match {
case None => find(tail, map)
case result @ Some(_) => result
}
}
}
迭代函数find():~25 ms
def find[A,B](list: scala.collection.immutable.List[A], map: A => Option[B]) : Option[B] = {
for (elem <- list) {
val result = map(elem)
if (result.isDefined) return result
}
return None
}
您可以通过使用 Java 而不是 Scala 集合和功能较少的样式来进一步加快速度。
在java.util.ArrayList 中循环索引:~15 ms
def find[A,B](list: java.util.ArrayList[A], map: A => Option[B]) : Option[B] = {
var i = 0
while (i < list.size()) {
val result = map(list.get(i))
if (result.isDefined) return result
i += 1
}
return None
}
循环java.util.ArrayList 中的索引,函数返回null 而不是None:~10 毫秒
def find[A,B](list: java.util.ArrayList[A], map: A => B) : Option[B] = {
var i = 0
while (i < list.size()) {
val result = map(list.get(i))
if (result != null) return Some(result)
i += 1
}
return None
}
(当然,通常将参数类型声明为java.util.List,而不是java.util.ArrayList。我在这里选择后者是因为它是我用于基准测试的类。java.util.List 的其他实现将显示不同的性能 -大多数情况会更糟。)