scala中ArrayBuffer和Array之间的区别是什么

时间:2015-07-03 20:19:07

标签: scala

我是scala / java的新手,我在解决这两个问题上遇到了麻烦。

通过阅读scala文档,我了解到ArrayBuffer是交互式的(追加,插入,前置等)。

1)基本的实施差异是什么?

2)这两者之间是否有性能差异?

感谢。

4 个答案:

答案 0 :(得分:31)

ArrayArrayBuffer都是可变的,这意味着您可以修改特定索引处的元素:a(i) = e

ArrayBuffer可调整大小,Array不可调整大小。如果将元素追加到ArrayBuffer,它会变大。如果您尝试将元素附加到Array,则会获得一个新数组。因此,为了有效地使用Array,您必须事先知道它的大小。

Array在JVM级别实现,是唯一的非擦除泛型类型。这意味着它们是存储对象序列的最有效方式 - 不会产生额外的内存开销,而某些操作则作为单个JVM操作码实现。

ArrayBuffer通过在内部设置Array来实现,并在需要时分配新的Array。附加通常是快速的,除非它达到限制并调整阵列的大小 - 但它以这样的方式完成,整体效果可以忽略不计,所以不要担心。预先实现为将所有元素向右移动并将新元素设置为第0个元素,因此它很慢。在循环中附加 n 元素是有效的( O n )),前置它们不是( O 名词的²))。

Unit专门用于内置值类型(Array[Int]除外),因此ArrayBuffer[Int]Array[T]更优化 - 值得胜'必须装箱,因此使用更少的内存和更少的间接。请注意,专门化一如既往仅适用于单形类型 - [Chosen Measure]:=SWITCH(TRUE, MIN(MeasureTable[Index])=1, [DistinctPatients], MIN(MeasureTable[Index])=2,[DistinctDates]) 将始终装箱。

答案 1 :(得分:2)

另一个区别是,Array的元素在声明时被创建,但是除非你第一次赋值,否则不会创建Array Buffer的元素。

例如。您可以首次编写Array1(0)="Stackoverflow"但不是ArrayBuffer1(0)="Stackoverflow"

(Array1 = Array variable& ArrayBuffer1 = ArrayBuffer variable)

因为我们知道,数组缓冲区是可调整大小的,所以在第一次插入值时创建的元素然后您可以在特定元素处修改/重新分配它们。

阵列:

为Int Array声明并赋值。

val favNums= new Array[Int](20)

for(i<-0 to 19){
favNums(i)=i*2
}
favNums.foreach(println)

ArrayBuffer:

为Int ArrayBuffer声明并赋值。

val favNumsArrayBuffer= new ArrayBuffer[Int]
    for(j<-0 to 19){
    favNumsArrayBuffer.insert(j, (j*2))
    //favNumsArrayBuffer++=Array(j*3)
      }
    favNumsArrayBuffer.foreach(println)

如果在for循环的第一行包含favNumsArrayBuffer(j)=j*2,则它不起作用。但是如果你在循环的第2行或第3行声明它,它可以正常工作。因为现在已经在第一行分配的值,您可以按元素索引进行修改。

这个简单的一小时视频教程解释了很多。

https://youtu.be/DzFt0YkZo8M?t=2005

答案 2 :(得分:2)

如果Array的长度是固定的,则使用数组;如果长度可以变化,则使用 ArrayBuffer

答案 3 :(得分:0)

另一个区别是参考和价值平等

Array(1,2) == Array(1,2)              // res0: Boolean = false
ArrayBuffer(1, 2) == ArrayBuffer(1,2) // res1: Boolean = true

==的差异是.equals routesArray.equals的原因,其中==是使用Java的public boolean equals(Object obj) { return (this == obj); } 来比较引用的

ArrayBuffer

ArrayBuffer.equals使用sameElements方法比较 override def equals(o: scala.Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || ( o match { case it: Seq[A] => (it eq this) || (it canEqual this) && sameElements(it) case _ => false } ) 包含的元素

contains

SimilarlyArray(Array(1,2)).contains(Array(1,2)) // res0: Boolean = false ArrayBuffer(ArrayBuffer(1,2)).contains(ArrayBuffer(1,2)) // res1: Boolean = true 的行为不同

public function modifyCollection(EndpointCollection $endpoints, ReflectionClass $class)
{
    foreach ($endpoints as $endpoint) {
        foreach ((array) $this->value as $middleware) {

            //Fix start
            if($multipleMiddlewares = explode(',', $middleware)){
                $middleware = '';
                $nbMiddlewares = count($multipleMiddlewares)-1;
                for($i=0; $i<=$nbMiddlewares; ++$i) {
                    $middleware .= $i > 0 ? "'" : '';
                    $middleware .= str_replace(' ', '', $multipleMiddlewares[$i]);
                    $middleware .= $i < $nbMiddlewares  ? "', " : '';
                }
            }
            //End of fix

            $endpoint->classMiddleware[] = [
                'name' => $middleware, 'only' => (array) $this->only, 'except' => (array) $this->except,
            ];
        }
    }
}