Guida rapida allo stack Java

1. Panoramica

In questo rapido articolo, introdurremo la classe java.util.Stack e inizieremo a vedere come utilizzarla.

Stack è una struttura di dati generica che rappresenta una raccolta di oggetti LIFO (last in, first out) che consente di spingere / esplodere elementi in tempo costante.

Per le nuove implementazioni, dovremmo preferire un'interfaccia Deque e le sue implementazioni . Deque definisce un insieme più completo e coerente di operazioni LIFO. Tuttavia, potremmo ancora aver bisogno di gestire la classe Stack , specialmente nel codice legacy, è importante conoscerla meglio.

2. Creare uno stack

Iniziamo creando un'istanza vuota di Stack , utilizzando il costruttore predefinito senza argomenti:

@Test public void whenStackIsCreated_thenItHasSizeZero() { Stack intStack = new Stack(); assertEquals(0, intStack.size()); }

Questo creerà uno Stack con la capacità predefinita di 10. Se il numero di elementi aggiunti supera la dimensione totale dello Stack , verrà raddoppiato automaticamente. Tuttavia, le sue dimensioni non si ridurranno mai dopo la rimozione degli elementi.

3. Sincronizzazione per Stack

Stack è una sottoclasse diretta di Vector ; questo significa che, analogamente alla sua superclasse, è un'implementazione sincronizzata .

Tuttavia, la sincronizzazione non è sempre necessaria, in questi casi si consiglia di utilizzare ArrayDeque .

4. Aggiungi in una pila

Iniziamo aggiungendo un elemento in cima allo Stack , con il metodo push () , che restituisce anche l'elemento che è stato aggiunto:

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

L'uso del metodo push () ha lo stesso effetto dell'uso di addElement (). L' unica differenza è che addElement () restituisce il risultato dell'operazione, invece dell'elemento che è stato aggiunto.

Possiamo anche aggiungere più elementi contemporaneamente:

@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. Recupera da uno stack

Successivamente, diamo un'occhiata a come ottenere e rimuovere l'ultimo elemento in uno Stack :

@Test public void whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() { Stack intStack = new Stack(); intStack.push(5); Integer element = intStack.pop(); assertEquals(Integer.valueOf(5), element); assertTrue(intStack.isEmpty()); }

Possiamo anche ottenere l'ultimo elemento della virata a S senza rimuoverlo:

@Test public void whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() { Stack intStack = new Stack(); intStack.push(5); Integer element = intStack.peek(); assertEquals(Integer.valueOf(5), element); assertEquals(1, intStack.search(5)); assertEquals(1, intStack.size()); }

6. Cerca un elemento in una pila

6.1. Ricerca

Stack ci consente di cercare un elementoe ottieni la sua distanza dall'alto:

@Test public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() { Stack intStack = new Stack(); intStack.push(5); intStack.push(8); assertEquals(2, intStack.search(5)); }

Il risultato è un indice di un dato oggetto. Se è presente più di un elemento, l'indice di quelloviene restituito il valore più vicino all'inizio . L'articolo che si trova in cima alla pila è considerato nella posizione 1.

Se l'oggetto non viene trovato, search () restituirà -1.

6.2. Ottenere l'indice dell'elemento

Per ottenere un indice di un elemento della S virata, possiamo anche usare l'indexOf () e lastIndexOf () metodi:

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

Il lastIndexOf () sarà sempre trovare l'indice dell'elemento che è più vicino alla cima alla pila . Funziona in modo molto simile a search () , con l'importante differenza che restituisce l'indice, invece della distanza dall'alto:

@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. Rimuovere gli elementi da una pila

Oltre all'operazione pop () , utilizzata sia per rimuovere che per recuperare elementi, possiamo anche utilizzare più operazioni ereditate dalla classe Vector per rimuovere elementi.

7.1. Rimozione di elementi specificati

Possiamo usare il metodo removeElement () per rimuovere la prima occorrenza dell'elemento dato:

@Test public void whenRemoveElementIsInvoked_thenElementIsRemoved() { Stack intStack = new Stack(); intStack.push(5); intStack.push(5); intStack.removeElement(5); assertEquals(1, intStack.size()); }

Possiamo anche usare removeElementAt () per eliminare elementi sotto un indice specificato nello Stack:

 @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. Rimozione di più elementi

Diamo una rapida occhiata a come rimuovere più elementi da uno Stack utilizzando l' API removeAll () , che prenderà una Collection come argomento e rimuoverà tutti gli elementi corrispondenti dallo Stack :

@Test public void givenElementsOnStack_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()); assertEquals(1, intStack.search(500)); }

È anche possibile rimuovere tutti gli elementi dalla pila usando l' clear () o removeAllElements () metodi ; entrambi i metodi funzionano allo stesso modo:

@Test public void whenRemoveAllElementsIsInvoked_thenAllElementsAreRemoved() { Stack intStack = new Stack(); intStack.push(5); intStack.push(7); intStack.removeAllElements(); assertTrue(intStack.isEmpty()); }

7.3. Rimozione di elementi utilizzando il filtro

Possiamo anche usare una condizione per rimuovere elementi dallo Stack. Vediamo come farlo usando removeIf () , con un'espressione di filtro come argomento:

@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. Iterate su uno stack

Stack allows us to use both an Iterator and a ListIterator. The main difference is that the first one allows us to traverse Stack in one direction and second allows us to do this in both 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)); }

All Iterators returned by Stack are fail-fast.

9. Stream API for the Java Stack

Stack is a collection, which means we can use it with Java 8 Streams API. Using Stream 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); List filtered = intStack .stream() .filter(element -> element <= 3) .collect(Collectors.toList()); assertEquals(3, filtered.size()); }

10. Summary

This tutorial is a quick and practical guide to understand this core class in Java – the Stack.

Ovviamente puoi esplorare l'API completa in Javadoc.

E, come sempre, tutti gli esempi di codice possono essere trovati su GitHub.