Kurzanleitung zum Java-Stack

Kurzanleitung zum Java Stack

1. Überblick

In diesem Artikel stellen wir die Klassejava.util.Stackvor und untersuchen, wie wir sie nutzen können.

Stack ist eine generische Datenstruktur, die eine LIFO-Sammlung (last in, first out) von Objekten darstellt, mit der Elemente in konstanter Zeit verschoben / gepoppt werden können.

2. Schaffung

Beginnen wir mit der Erstellung einer leeren Instanz vonStack unter Verwendung des Standardkonstruktors ohne Argumente:

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

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

Dies wirdcreate a Stack with the default capacity of 10. Wenn die Anzahl der hinzugefügten Elemente die Gesamtgröße vonStacküberschreitet, wird sie automatisch verdoppelt. Seine Größe wird jedoch nach dem Entfernen von Elementen niemals kleiner.

3. Synchronisation

Stack ist eine direkte Unterklasse vonVector; Dies bedeutet, dasssimilarly to its superclass, it’s asynchronizedimplementation.

Eine Synchronisierung ist jedoch nicht immer erforderlich. In solchen Fällen wird empfohlen,ArrayDeque zu verwenden.

4. Hinzufügen

Beginnen wir mit dem Hinzufügen eines Elements am Anfang vonStack mit der Methodepush(), die auch das hinzugefügte Element zurückgibt:

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

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

Die Verwendung der Methodepush() hat den gleichen Effekt wie die Verwendung vonaddElement(). *T*he only difference is that addElement() returns the result of the operation, instead of the element that was added.

Wir können auch mehrere Elemente gleichzeitig hinzufügen:

@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. Abrufen

Als nächstes schauen wir uns an, wie das letzte Element inStack abgerufen und entfernt wird:

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

    assertTrue(intStack.isEmpty());
}

Wir können auch das letzte Element der Stackerhalten, ohne es zu entfernen:

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

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

6. Suche nach einem Element

Stack ermöglicht es uns, nach einem Element __ zu suchen und dessen Abstand von oben zu ermitteln:

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

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

Das Ergebnis ist ein Index vonObject. Wenn mehr als einObject vorhanden ist, wird der Index vonObject zurückgegeben, der der Spitze am nächsten liegt. Der Gegenstand, der sich oben auf dem Stapel befindet, befindet sich an Position 1.

WennObject nicht gefunden wird, gibtsearch() -1 zurück.

6.2. Index des Elements abrufen

Um einen Index eines Elements für die Stack, zu erhalten, können wir auch die MethodenindexOf() undlastIndexOf() verwenden:

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

    assertEquals(0, indexOf);
}

DielastIndexOf() finden immer den Index des Elements, das dem oberen Rand des Stapels am nächsten liegt. Dies funktioniert sehr ähnlich wiesearch() - mit dem wichtigen Unterschied, dassit returns the index anstelle des Abstands von oben:

@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. Elemente entfernen

Abgesehen von der Operationpop(), die sowohl zum Entfernen als auch zum Abrufen von Elementen verwendet wird, können wir auch mehrere Operationen verwenden, die von der KlasseVectorgeerbt wurden, um Elemente zu entfernen.

7.1. Bestimmte Elemente entfernen

Wir können die MethoderemoveElement() verwenden, um das erste Auftreten eines bestimmten Elements zu entfernen:

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

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

Wir können auchremoveElementAt() verwenden, um Elemente unter einem bestimmten Index inStack: zu löschen

@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. Mehrere Elemente entfernen

Lassen Sie uns einen kurzen Blick darauf werfen, wie Sie mehrere Elemente aus einemStack mithilfe derremoveAll()-API entfernen. Dabei wird einCollection als Argument verwendet und alle übereinstimmenden Elemente ausStackentfernt. s:

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

Es ist auch möglich, alle Elemente mit den Methodenclear() oderremoveAllElements() ausStack zu entfernen. Beide Methoden funktionieren gleich:

@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. Elemente mit Filter entfernen

Wir können auch eine Bedingung zum Entfernen von Elementen ausStack. verwenden. Sehen wir uns an, wie dies mitremoveIf() mit einem Filterausdruck als Argument gemacht wird:

@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. Iterieren

Stack ermöglicht es uns, sowohl einIterator als auch einListIterator. zu verwenden. Der Hauptunterschied besteht darin, dass der erste es uns ermöglicht,Stack in eine Richtung zu durchlaufen, und der zweite ermöglicht dies Beide Richtungen:

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

Alle vonStack zurückgegebenenIterators sind ausfallsicher.

9. Stream-API

A Stack ist eine Sammlung, was bedeutet, dass wir sie mit Java 8Streams API verwenden können. 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. Zusammenfassung

Dieses Tutorial war eine Kurzanleitung zum Verständnis der JavaStack. Weitere Informationen zu diesem Thema finden Sie unterJavadoc.

Und wie immer können alle Codebeispieleover on Github gefunden werden.