Guide rapide de la pile Java

Guide rapide de la pile Java

1. Vue d'ensemble

Dans cet article, nous allons présenter la classejava.util.Stack et commencer à voir comment nous pouvons l'utiliser.

LeStack est une structure de données générique qui représente une collection LIFO (dernier entré, premier sorti) d'objets permettant de pousser / sauter des éléments en temps constant.

2. Création

Commençons par créer une instance vide deStack, en utilisant le constructeur par défaut sans argument:

@Test
public void whenStackIsCreated_thenItHasSize0() {
    Stack intStack = new Stack();

    assertEquals(0, intStack.size());
}

Ceci seracreate a Stack with the default capacity of 10. Si le nombre d'éléments ajoutés dépasse la taille totale deStack, il sera doublé automatiquement. Cependant, sa taille ne sera jamais réduite après la suppression d'éléments.

3. Synchronisation

Stack est une sous-classe directe deVector; cela signifie quesimilarly to its superclass, it’s asynchronizedimplementation.

Cependant, la synchronisation n’est pas toujours nécessaire, dans ce cas, il est conseillé d’utiliserArrayDeque.

4. Ajouter

Commençons par ajouter un élément en haut desStack, avec la méthodepush() - qui renvoie également l'élément qui a été ajouté:

@Test
public void whenElementIsPushed_thenStackSizeIsIncreased() {
    Stack intStack = new Stack();
    intStack.push(1);

    assertEquals(1, intStack.size());
}

L'utilisation de la méthodepush() a le même effet que l'utilisation deaddElement(). *T*he only difference is that addElement() returns the result of the operation, instead of the element that was added.

Nous pouvons également ajouter plusieurs éléments à la fois:

@Test
public void whenMultipleElementsArePushed_thenStackSizeisIncreased() {
    Stack intStack = new Stack();
    List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    boolean result = intStack.addAll(intList);

    assertTrue(result);
    assertEquals(7, intList.size());
}

5. Récupération

Voyons ensuite comment obtenir et supprimer le dernier élément d'unStack:

@Test
public void whenElementIsPoppedFromStack_thenSizeChanges() {
    Stack intStack = new Stack();
    intStack.push(5);
    intStack.pop();

    assertTrue(intStack.isEmpty());
}

On peut aussi récupérer le dernier élément des Stack sans le supprimer:

@Test
public void whenElementIsPeeked_thenElementIsNotRemoved() {
    Stack intStack = new Stack();
    intStack.push(5);
    intStack.peek();

    assertEquals(1, intStack.search(5));
    assertEquals(1, intStack.size());
}

6. Recherche d'un élément

Stack nous permet de rechercher un élément __ et d'obtenir sa distance du haut:

@Test
public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() {
    Stack intStack = new Stack();
    intStack.push(5);

    assertEquals(1, intStack.search(5));
}

Le résultat est un indice deObject donnés. Si plus d'unObject est présent, l'index deObject le plus proche du sommet est renvoyé. L'élément qui se trouve en haut de la pile est considéré comme étant à la position 1.

Si leObject n'est pas trouvé,search() renverra -1.

6.2. Obtenir l'index de l'élément

Pour obtenir un index d'un élément sur les Stack, nous pouvons aussi utiliser les méthodesindexOf() etlastIndexOf():

@Test
public void whenElementIsOnStack_thenIndexOfReturnsItsIndex() {
    Stack intStack = new Stack();
    intStack.push(5);
    int indexOf = intStack.indexOf(5);

    assertEquals(0, indexOf);
}

LeslastIndexOf() trouveront toujours l’index de l’élément le plus proche du haut de la pile. Cela fonctionne de manière très similaire àsearch() - avec la différence importante queit returns the index, au lieu de la distance par rapport au sommet:

@Test
public void whenMultipleElementsAreOnStack_thenIndexOfReturnsLastElementIndex() {
    Stack intStack = new Stack();
    intStack.push(5);
    intStack.push(5);
    intStack.push(5);
    int lastIndexOf = intStack.lastIndexOf(5);

    assertEquals(2, lastIndexOf);
}

7. Supprimer des éléments

En dehors de l'opérationpop(), utilisée à la fois pour supprimer et récupérer des éléments, nous pouvons également utiliser plusieurs opérations héritées de la classeVector pour supprimer des éléments.

7.1. Suppression d'éléments spécifiés

Nous pouvons utiliser la méthoderemoveElement() pour supprimer la première occurrence d'un élément donné:

@Test
public void whenRemoveElementIsInvoked_thenElementIsRemoved() {
    Stack intStack = new Stack();
    intStack.push(5);
    intStack.push(5);
    intStack.removeElement(5);

    assertEquals(1, intStack.size());
}

Nous pouvons également utiliser lesremoveElementAt() pour supprimer des éléments sous un index spécifié dans lesStack:

@Test
public void whenRemoveElementAtIsInvoked_thenElementIsRemoved() {
    Stack intStack = new Stack();
    intStack.push(5); intStack.push(7);
    intStack.removeElementAt(1);

    assertEquals(-1, intStack.search(7));
}

7.2. Suppression de plusieurs éléments

Voyons rapidement comment supprimer plusieurs éléments d'unStack en utilisant l'APIremoveAll() - qui prendra unCollection comme argument et supprimera tous les éléments correspondants duStack:

@Test
public void whenRemoveAllIsInvoked_thenAllElementsFromCollectionAreRemoved() {
    Stack intStack = new Stack();
    List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    intStack.addAll(intList);
    intStack.add(500);
    intStack.removeAll(intList);

    assertEquals(1, intStack.size());
}

Il est également possible de supprimer tous les éléments desStack en utilisant les méthodesclear() ouremoveAllElements(); ces deux méthodes fonctionnent de la même manière:

@Test
public void whenRemoveIfIsInvoked_thenAllElementsSatysfyingConditionAreRemoved() {
    Stack intStack = new Stack();
    List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    intStack.addAll(intList);
    intStack.removeIf(element -> element < 6);

    assertEquals(2, intStack.size());
}

7.3. Suppression d'éléments à l'aide d'un filtre

Nous pouvons également utiliser une condition pour supprimer des éléments desStack. Voyons comment faire cela en utilisant lesremoveIf(), avec une expression de filtre comme argument:

@Test
public void whenRemoveIfIsInvoked_thenAllElementsSatysfyingConditionAreRemoved() {
    Stack intStack = new Stack();
    List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    intStack.addAll(intList);
    intStack.removeIf(element -> element < 6);

    assertEquals(2, intStack.size());
}

8. Itérer

Stack nous permet d'utiliser à la fois unIterator et unListIterator. La principale différence est que le premier nous permet de traverserStack dans un sens et le second permet de le faire en les deux directions:

@Test
public void whenAnotherStackCreatedWhileTraversingStack_thenStacksAreEqual() {
    Stack intStack = new Stack<>();
    List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    intStack.addAll(intList);
    ListIterator it = intStack.listIterator();
    Stack result = new Stack();
    while(it.hasNext()) {
        result.push(it.next());
    }

    assertThat(result, equalTo(intStack));
}

Tous lesIterators renvoyés parStack sont en échec rapide.

9. API de flux

A Stack est une collection, ce qui signifie que nous pouvons l'utiliser avec Java 8Streams API. Using Streams with the Stack is similar to using it with any other Collection:

@Test
public void whenStackIsFiltered_allElementsNotSatisfyingFilterConditionAreDiscarded() {
    Stack intStack = new Stack();
    List inputIntList = Arrays.asList(1, 2, 3, 4, 5, 6, 7,9,10);
    intStack.addAll(inputIntList);
    int[] intArray = intStack.stream()
      .mapToInt(element -> (int)element)
      .filter(element -> element <= 3)
      .toArray();

    assertEquals(3, intArray.length);
}

10. Sommaire

Ce tutoriel était un guide rapide pour comprendre lesStack Java. Pour en savoir plus sur ce sujet, reportez-vous àJavadoc.

Et, comme toujours, tous les échantillons de code peuvent être trouvésover on Github.