Scala使用toSet.toList和distinct有何区别?

12

如果我想获取List中的唯一元素,我可以使用distinct或者调用toSet.toList。哪一个更有效率,为什么?还有其他有效的方法吗?我的理解是distinct会保持顺序,而toSet.toList不会。

scala> val mylist = List(1,2,3,3,4,4,4,5,6,6,6,6,7)
mylist: List[Int] = List(1, 2, 3, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7)

scala> mylist.distinct
res11: List[Int] = List(1, 2, 3, 4, 5, 6, 7)

scala> mylist.toSet.toList
res12: List[Int] = List(5, 1, 6, 2, 7, 3, 4)
1个回答

9

以下内容直接来源于此处的源代码:

/** Builds a new $coll from this $coll without any duplicate elements.
* $willNotTerminateInf
*
* @return A new $coll which contains the first occurrence of every element of this $coll.
*/
  def distinct: Repr = {
    val b = newBuilder
    val seen = mutable.HashSet[A]()
    for (x <- this) {
      if (!seen(x)) {
        b += x
        seen += x
      }
    }
    b.result
  }

因此,看起来如果保留顺序很重要,使用distinct,否则它们的代价相对较高。

顺便提一下,“distinct”实现不是函数式的,使用了可变状态和vals。有什么原因吗? - Soumya Simanta
12
它执行的计算是单线程的。它使用的可变集合在该方法外部不可观察。它积累的副作用与使用不可变结构和纯函数编程的任何优势无关。最后,它几乎肯定比使用不可变累加器集编写时要快得多(真正意义上的“显著”,而非“实质性”的同义词)。 - Randall Schulz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接