Java 反转堆栈并添加到ArrayList的最有效方法
我有两个集合-一个ArrayList和一个Stack。我使用堆栈是因为我需要一些简单的pop/push功能来处理这段代码。ArrayList本质上是out变量,因为这是函数中的一小部分代码 因此,变量是这样定义的,然后运行代码将元素添加到堆栈中Java 反转堆栈并添加到ArrayList的最有效方法,java,data-structures,performance,stack,arraylist,Java,Data Structures,Performance,Stack,Arraylist,我有两个集合-一个ArrayList和一个Stack。我使用堆栈是因为我需要一些简单的pop/push功能来处理这段代码。ArrayList本质上是out变量,因为这是函数中的一小部分代码 因此,变量是这样定义的,然后运行代码将元素添加到堆栈中 ArrayList<String> out = new ArrayList<String>(); /* other code.. */ Stack<String> lineStack = new Stack<
ArrayList<String> out = new ArrayList<String>();
/* other code.. */
Stack<String> lineStack = new Stack<String>();
/* code that adds stuff to the stack */
。。。这是可行的,但我担心在ArrayList的开头添加一个元素的效率(这会迫使所有现有元素都需要移动..这是一个链表(我相信..很重要..但仍然是一个问题)。另外,我正在通过一个循环运行这个。。。也许是不必要的
因此,我的第二个解决方案不涉及循环(至少在我的代码中,我确信后端调用正在这样做)
我知道我不需要分配这个列表,但它会保留下来,以便代码更清晰。但是,我不确定这是否会给我带来特别有用的性能提升
所以,我的问题是:对于中小型设备,哪一种可能最有效?如果有一个更有效的解决方案,它会是什么?对ArrayList进行子类化,并添加一个pop-and-push方法。 将其用作堆栈类 准备好后,将其分配给Arraylist变量,就准备好了堆栈的
Iterable
实现顺序将按照您想要的顺序进行,因此您可以使用
new ArrayList<String>(stack);
(这与你打开它们的顺序相反)
编辑:还有一个问题-你真的需要在
ArrayList
中使用它吗<代码>堆栈实现列表
;您需要ArrayList
的哪些特殊功能?(我不是说你不需要它们,只是检查一下!)使用Stack.toArray很简单:
@Test
public void stackToList() {
Stack<String> stack = new Stack<String>();
stack.push("aaa");
stack.push("bbb");
stack.push("ccc");
List<String> list= Arrays.asList(stack.toArray(new String[0]));
Assert.assertEquals(Arrays.asList("aaa", "bbb", "ccc"), list);
}
@测试
公共空间堆栈列表(){
堆栈=新堆栈();
堆栈推送(“aaa”);
堆栈推送(“bbb”);
堆栈推送(“ccc”);
List List=Arrays.asList(stack.toArray(新字符串[0]);
Assert.assertEquals(Arrays.asList(“aaa”、“bbb”、“ccc”)、list);
}
如果您不需要它作为数组,但另一个堆栈可以工作,为什么不:
Stack reversedStack=new Stack();
而(!oldStack.empty())
{
reversedStack.push(oldStack.pop());
}
快速、简单且易于查看它在做什么。堆栈是集合的子类,集合有,所以您只需-
Stack originalStack = ...
Collections.reverse(originalStack);
添加到
ArrayList
的开头成本很高;它是一个数组列表
而不是链接列表
。将它添加到开头是O(n^2)
。请注意Stack
是Vector
的一个子类(它几乎类似于ArrayList
)。出院时,也许你可以把它当作向量,而不是复制列表。这就是我想的。原来我只是使用out.addAll(lineStack)方法。我甚至不需要把它变成一个列表对象。这是不必要的开销。堆栈的迭代器将朝着正确的方向运行,尽管它是一个堆栈。你说得很好!我无法重新初始化ArrayList(不能保证为空),但由于迭代器将以正确的顺序将其提供给我,因此我可以直接输出.addAll(lineStack)。。我不知道为什么我要费心把它列成一个清单。谢谢!编辑:是。ArrayList正在其他地方使用,并且是API的一部分-无法真正更改它:(.这是绝对公平的。我将把编辑留给后代,以防其他人发现自己处于类似的情况,但他们可以使用堆栈:)这很有效,因为stack
实现List
,不是因为堆栈
是集合
;查看参数类型以Collections#reverse
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Stack<String> stack = new Stack<String>();
stack.push("Bottom");
stack.push("Middle");
stack.push("Top");
List<String> list = new ArrayList<String>(stack);
for (String x : list)
{
System.out.println(x);
}
}
}
Bottom
Middle
Top
@Test
public void stackToList() {
Stack<String> stack = new Stack<String>();
stack.push("aaa");
stack.push("bbb");
stack.push("ccc");
List<String> list= Arrays.asList(stack.toArray(new String[0]));
Assert.assertEquals(Arrays.asList("aaa", "bbb", "ccc"), list);
}
Stack originalStack = ...
Collections.reverse(originalStack);