ArrayDeque vs ArrayList实现堆栈

时间:2015-04-11 21:18:53

标签: java arraylist stack arraydeque

ArrayDeque的文档说:

  

当用作堆栈时,此类可能比Stack快,并且在用作队列时比LinkedList更快。

没有提及使用ArrayDeque作为堆栈和使用ArrayList之间的区别。您可以使用ArrayList作为堆栈,如下所示。

list.add(object);                      // push
object = list.remove(list.size() - 1); // pop

我发现当我以这种方式使用ArrayList时,其性能比ArrayDeque差。这种差异的原因是什么?当然,它不仅仅是对size()的呼叫?在内部,ArrayListArrayDeque都使用Object[]实现,在需要时由更大的数组替换,所以性能肯定应该大致相同?

1 个答案:

答案 0 :(得分:18)

两种实施方式的主要区别在于调整大小策略

  • ArrayList的大小调整为oldCapacity + (oldCapacity >> 1),大小增加了~50%。默认容量为10,在调整大小后产生容量15,22,33,49,73,109,163,244,366 ...

  • ArrayDeque总是调整为2的幂。在调整大小时,容量加倍。从默认值16开始,调整大小后的结果容量为32,64,128,256,...

因此,ArrayDeque可以通过更少的调整大小操作来实现更高的容量,由于阵列复制,这些代价很高。即要在默认大小的ArrayList中存储256,它需要9次调整大小调用,而ArrayDeque只需要4。 阵列复制可能很快,但除了内存复制成本之外,还可能需要GC为新数据集释放一些空间(其中ArrayDeque也可能因为它与电源的对齐而更好地执行) 2)。

这两个数据结构都具有O(1)的最佳案例复杂性,用于通过headtail上的直接访问进行推送和弹出。 size(ArrayDequeue)分别添加和删除(Last)var newSizeBitmapData:BitmapData = resizeBitmapData(myBitmapData, newWidth, newHeight); /** * Resize display object or bitmap data to a new size **/ public static function resizeBitmapData(bitmapDrawable:IBitmapDrawable, width:Number, height:Number, scaleMode:String="none", smooth:Boolean = true, transparent:Boolean = true, fillColor:Number = 0x00000000):BitmapData { var sizedBitmapData:BitmapData; var matrix:Matrix; matrix = getSizeByScaleMode(width, height, Object(bitmapDrawable).width, Object(bitmapDrawable).height, scaleMode); sizedBitmapData = new BitmapData(width, height, transparent, fillColor); sizedBitmapData.draw(bitmapDrawable, matrix, null, null, null, smooth); return sizedBitmapData; } // Get correct scale. Inspired from code in Apache Flex (license Apache 2.0) public static function getSizeByScaleMode(maxWidth:int, maxHeight:int, width:int, height:int, scaleMode:String="letterbox", dpi:Number=NaN):Matrix { var aspectRatio:String = (maxWidth < maxHeight) ? "portrait" : "landscape"; var orientation:String = aspectRatio; var matrix:Matrix = new Matrix(); var scaleX:Number = 1; var scaleY:Number = 1; switch(scaleMode) { case "zoom": scaleX = Math.max( maxWidth / width, maxHeight / height); scaleY = scaleX; break; case "letterbox": scaleX = Math.min( maxWidth / width, maxHeight / height); scaleY = scaleX; break; case "stretch": scaleX = maxWidth / width; scaleY = maxHeight / height; break; } if (scaleX != 1 || scaleY != 0) { width *= scaleX; height *= scaleY; matrix.scale(scaleX, scaleY); } matrix.translate(-width / 2, -height / 2); matrix.translate(maxWidth / 2, maxHeight / 2); return matrix; } (ArrayList)