如何在Java中复制一个堆栈?

22

我有一个堆栈A,想要创建一个与堆栈A相同的堆栈B。我不希望堆栈B只是指向A的指针,我实际上想要创建一个包含与堆栈A相同元素且按照相同顺序的新堆栈B。堆栈A是字符串的堆栈。

谢谢!


1
Stack<String> b = (Stack<String>) a.clone(); - Marcelo
6个回答

32

只需使用Stack类的clone()方法(该类实现了Cloneable)。

以下是一个使用JUnit的简单测试用例:

@Test   
public void test()
{
    Stack<Integer> intStack = new Stack<Integer>();
    for(int i = 0; i < 100; i++)        
    {
        intStack.push(i);
    }

    Stack<Integer> copiedStack = (Stack<Integer>)intStack.clone();

    for(int i = 0; i < 100; i++)            
    {
        Assert.assertEquals(intStack.pop(), copiedStack.pop());
    }
}

编辑:

tmsimont:这会给我创建一个“未经检查或不安全的操作”警告。有没有方法可以在不生成此问题的情况下完成此操作?

起初我的回应是无法避免警告,但实际上可以使用<?>(通配符)类型来避免:

@Test
public void test()
{
    Stack<Integer> intStack = new Stack<Integer>();
    for(int i = 0; i < 100; i++)
    {
        intStack.push(i);
    }

    //No warning
    Stack<?> copiedStack = (Stack<?>)intStack.clone();

    for(int i = 0; i < 100; i++)
    {
        Integer value = (Integer)copiedStack.pop(); //Won't cause a warning, no matter to which type you cast (String, Float...), but will throw ClassCastException at runtime if the type is wrong
        Assert.assertEquals(intStack.pop(), value);
    }
}

我认为您仍在从 ?(未知类型)向 Integer 进行未经检查的强制类型转换,但没有警告。个人而言,我更喜欢直接转换成 Stack<Integer> 并使用 @SuppressWarnings("unchecked") 来抑制警告。


这会为我创建一个“未经检查或不安全的操作”警告。有没有方法可以避免出现这个问题? - tmsimont
1
@tmsimont:请忽略我之前的评论,查看已编辑的答案,可以在不使用@SuppressWarnings("unchecked")的情况下防止警告。 - esaj
1
谢谢。这是疯狂的。 - Script Kitty

22

Stack 扩展自 Vector,因此您只需新建一个 Stack 并使用 .addAll(...) 来复制项目:

Stack<Type> newStack = new Stack<Type>();
newStack.addAll(oldStack);

3
这不会复制成员项目。两个栈将指向同样的字符串。 - Steve J
3
字符串是不可变的,因此复制字符串并没有任何帮助。 - clstrfsck

4

Stack 类是 AbstractList 的子类。

只需将其视为 AbstractList,在堆栈中使用 get(int index) 方法迭代元素,从 0 到列表/堆栈的长度,并将元素添加到新堆栈中。

这不会复制元素-它将元素添加到新堆栈中。如果您还需要复制元素,您需要再深入一层并创建元素的副本,然后将其添加到新堆栈中。

您可以使用 clone 方法进行 完全(或“深层”)复制, 但请注意对象必须实现 Clonable 接口才能获得 对象的深度复制


0

0
 /**
     * Copy constructor for the Stack class
     * @param original the Stack to copy
     * @postcondition a new Stack object which is
     * an identical, but distinct, copy of original
     */
    public Stack(Stack<T> original) {
        if (original.length == 0)
        {
            length = 0;
            top = null;
        } else
        {
            Node temp = original.top;
            while (temp != null)
            {
                push(temp.data); // inserts into this
                temp = temp.next;
            }
            temp = top;
            temp = temp.next;
            top.next = null;
            while (temp != null){
                push(temp.data); // inserts into this
                temp = temp.next;
            }

        }
    }

3
这几乎与您刚发布的另一个答案完全相同。Stack Overflow不允许重复的回答。请删除您发布的其中一个答案。 - Pika Supports Ukraine

-1
 /**
 * Copy constructor for the Stack class
 * @param original the Stack to copy
 * @postcondition a new Stack object which is
 * an identical, but distinct, copy of original
 */
public Stack(Stack<T> original) {
    if (original.length == 0)
    {
        length = 0;
        top = null;
    } else
    {
        Node temp = original.top;
        while (temp != null)
        {
            push(temp.data); // inserts into this
            temp = temp.next;
        }
        temp = top;
        temp = temp.next;
        top.next = null;
        while (temp != null){
            push(temp.data); // inserts into this
            temp = temp.next;
        }

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接