web-dev-qa-db-fra.com

Comment copier une pile en Java?

J'ai une pile A et je veux créer une pile B identique à la pile A. Je ne veux pas que la pile B soit simplement un pointeur sur A - je veux en fait créer une nouvelle pile B contenant les mêmes éléments en tant que pile A dans le même ordre que la pile A. La pile A est une pile de chaînes.

Merci!

19
Pankaj Udhas

Utilisez simplement la méthode clone () de la classe Stack (elle implémente Cloneable).

Voici un cas de test simple avec 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());
    }
}

Modifier:

tmsimont: Cela crée un avertissement "opérations non contrôlées ou non sécurisées" pour moi. Tout Moyen de le faire sans générer ce problème?

J'ai d'abord répondu que l'avertissement serait inévitable, mais en réalité, il est évitable d'utiliser <?> (caractère générique):

@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);
    }
}

En gros, je dirais que vous faites toujours un transtypage non contrôlé de ? (type inconnu) à Integer, mais il n'y a pas d'avertissement. Personnellement, je préférerais toujours lancer directement dans Stack<Integer> et supprimer l'avertissement avec @SuppressWarnings("unchecked").

24
esaj

Stack prolonge Vector, vous pouvez donc créer une nouvelle Stack et utiliser .addAll(...) pour copier les éléments:

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

Le Stack class est une sous-classe de AbstractList .

Traitez-le simplement comme une AbstractList, parcourez les éléments de la pile à l'aide de la méthode get(int index), de 0 à la longueur de votre liste/pile, et ajoutez les éléments à la nouvelle pile.

Cela ne copiera pas les éléments, mais les ajoutera à la nouvelle pile. Si vous devez également copier les éléments, vous devrez approfondir un autre niveau, créer des copies des éléments et les ajouter à la nouvelle pile.

Vous pouvez faire des copies complètes (ou "profondes") , en utilisant la méthode clone, mais notez que l’objet doit implémenter l’interface Clonable pour obtenir les copies complètes de objets .

4
jefflunt

Vous voulez utiliser la méthode clone .

0
Grammin
 /**
     * 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;
            }

        }
    }
0
jerry li