编程语言
首页 > 编程语言> > java-Scala:从返回Seq的函数中返回可变缓冲区

java-Scala:从返回Seq的函数中返回可变缓冲区

作者:互联网

当我从Java列表转换为通用Scala Seq时,我想更好地了解这段代码中实际发生的事情:

import scala.collection.JavaConverters._

def foo(javaList: java.util.List[String]): Seq[String] = {
  val scalaMutableBuffer: mutable.Buffer[String] = javaList.asScala
  scalaMutableBuffer
}

... 

val bar = foo(someJavaList)

我是否正确理解,虽然bar被键入为Seq [String],但它在底层使用了可变缓冲区,可能会影响Seq操作的性能? Seq是仅通过Seq特性的约束来指代缓冲区,还是存在进行中的实际基础转换?最好将价值栏包含为可变的或不变的吗?

请原谅这个问题的开放性,但是我觉得我对发生的事情没有一个很好的主意,我想改变一下.例如,在任何情况下,从foo返回之前,我最好将scalaMutableBuffer转换为List吗?

谢谢!

解决方法:

while bar is typed as a Seq[String], it’s using a mutable buffer on
an underlying level

没错,bar的运行时值是mutable.ArrayBuffer [String](因为Buffer本身就是特征),而Seq [A]是特征,作为调用者,您只能看到“序列” ”,尽管您始终可以通过buffer.asInstanceOf [mutable.ArrayBuffer [String]]将其强制转换为缓冲区,然后查看缓冲区的实际“内部”.

potentially affecting the performance of Seq operations

当暴露一个Seq [A]时,您就暴露了基础集合所遵循的“合同”.在运行时,它将始终是一个具体的实现.即,当我们通过apply创建Seq时:

scala> Seq(1,2,3)
res0: Seq[Int] = List(1, 2, 3)

具体的实现实际上是一个List [Int].

Would it be best to think of the value bar contains as mutable or
immutable?

基础实现是可变的,但是通过不可变的契约公开.这意味着当您通过抽象Seq特性来在缓冲区上进行操作时,没有任何可变操作可用作调用方.

例如,当我们这样做时:

scala> val bufferAsSeq: Seq[Int] = scala.collection.mutable.Buffer(1,2,3)
bufferAsSeq: Seq[Int] = ArrayBuffer(1, 2, 3)

scala> bufferAsSeq += 4
<console>:12: error: value += is not a member of Seq[Int]
       bufferAsSeq += 4

抽象防止我们让用户调用我们不希望他们在运行时类型上执行的操作.

For example, would there be any cases in which it would be preferable
for me to convert scalaMutableBuffer toList before returning from foo

我认为这主要是基于意见的.如果您不感到Seq特性,则可以始终使具体类型为不可变的.但是请记住,为了使某人变异Seq的副本,他必须检查运行时类型并将其显式强制转换为该类型,并且在您强制转换时所有赌注都已关闭.

标签:seq,scala,type-conversion,mutable,java
来源: https://codeday.me/bug/20191026/1938866.html