假设我有case class SamplePair(
arrayOfNumbers: ArrayBuffer[Int]
)
用于某种目的。
sequenceOfSamplePair
假设我Seq
有一个基本SamplePair
的{{1}},我想在每个元素的arrayOfNumbers
元素中添加一些有序数字。
一种方法是这样做:
val ctr = new AtomicInteger(0)
sequenceOfSamplePair.foreach{ entry =>
entry.arrayOfNumbers += ctr.getAndIncrement()
}
另一种方法是使用zipWithIndex
执行此操作。
sequenceOfSamplePair.zipWithIndex.foreach {
case (entry, ctr) =>
entry.arrayOfNumbers += ctr
}
使用zipWithIndex
更喜欢实施的原因是什么?是否更多"功能性"?
答案 0 :(得分:2)
由于您的两种方法都不起作用,我会选择第一种方法。 在第二种方法中,您将功能构造与命令式构造混合在一起,而您却失去了从功能性解决方案中获得的所有收益。
在案例类中使用可变缓冲区也不能使用可变缓冲区。
更具功能性的方法可能看起来像
case class SamplePair(numbers: List[Int])
val extendedSequenceOfSamplePair = sequenceOfSamplePair.zipWithIndex.map {
case ( sp@SamplePair(oldNumbers), idx) => sp.copy( numbers = idx :: oldNumbers)
}
答案 1 :(得分:2)
我刚用这两种方法做了一些分析。没有明显的赢家。如果zipWithIndex
中的模式匹配替换为直接引用(_1
和_2
),那么它会稍微快一点,但仍然不是明显的赢家。
但是,如果你使用如下流媒体:
Stream.range(0, sequenceOfSamplePair.length).map { i =>
sequenceOfSamplePair(i) += i
}
那么,它的速度提高了约6倍。这是因为它非常简单,只需逐个通过柜台,直接添加到数字。 6x速度要快得多,这意味着getAndIncrement
似乎使相对而言非常非常慢。