Guia rápido para Java Stack
1. Visão geral
Neste artigo, vamos apresentar a classejava.util.Stack e começar a ver como podemos fazer uso dela.
OStack é uma estrutura de dados genérica que representa uma coleção de objetos LIFO (último a entrar, primeiro a sair) permitindo empurrar / estourar elementos em tempo constante.
2. Criação
Vamos começar criando uma instância vazia deStack, usando o construtor padrão, sem argumento:
@Test
public void whenStackIsCreated_thenItHasSize0() {
Stack intStack = new Stack();
assertEquals(0, intStack.size());
}
Isso serácreate a Stack with the default capacity of 10. Se o número de elementos adicionados exceder o tamanho total deStack, ele será duplicado automaticamente. No entanto, seu tamanho nunca diminui após a remoção dos elementos.
3. Sincronização
Stack é uma subclasse direta deVector; isso significa quesimilarly to its superclass, it’s asynchronizedimplementation.
No entanto, a sincronização nem sempre é necessária, em tais casos, é aconselhável usarArrayDeque.
4. Adicionando
Vamos começar adicionando um elemento ao topo deStack, com o métodopush() - que também retorna o elemento que foi adicionado:
@Test
public void whenElementIsPushed_thenStackSizeIsIncreased() {
Stack intStack = new Stack();
intStack.push(1);
assertEquals(1, intStack.size());
}
Usar o métodopush() tem o mesmo efeito que usaraddElement(). *T*he only difference is that addElement() returns the result of the operation, instead of the element that was added.
Também podemos adicionar vários elementos ao mesmo tempo:
@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. Recuperando
A seguir, vamos dar uma olhada em como obter e remover o último elemento em umStack:
@Test
public void whenElementIsPoppedFromStack_thenSizeChanges() {
Stack intStack = new Stack();
intStack.push(5);
intStack.pop();
assertTrue(intStack.isEmpty());
}
Também podemos obter o último elemento de Stack sem removê-lo:
@Test
public void whenElementIsPeeked_thenElementIsNotRemoved() {
Stack intStack = new Stack();
intStack.push(5);
intStack.peek();
assertEquals(1, intStack.search(5));
assertEquals(1, intStack.size());
}
6. Procurando um Elemento
6.1. Procurar
Stack nos permite pesquisar um elemento __ e obter sua distância do topo:
@Test
public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() {
Stack intStack = new Stack();
intStack.push(5);
assertEquals(1, intStack.search(5));
}
O resultado é um índice deObject fornecido. Se mais de umObject estiver presente, o índice deObject mais próximo do topo será retornado. O item que está no topo da pilha é considerado na posição 1.
SeObject não for encontrado,search() retornará -1.
6.2. Obtendo Índice de Elemento
Para obter um índice de um elemento em Stack,, também podemos usar os métodosindexOf()elastIndexOf():
@Test
public void whenElementIsOnStack_thenIndexOfReturnsItsIndex() {
Stack intStack = new Stack();
intStack.push(5);
int indexOf = intStack.indexOf(5);
assertEquals(0, indexOf);
}
OlastIndexOf() sempre encontrará o índice do elemento que está mais próximo do topo da pilha. Isso funciona de forma muito semelhante asearch() - com a importante diferença deit returns the index, em vez da distância do topo:
@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. Removendo elementos
Além da operaçãopop(), usada para remover e recuperar elementos, também podemos usar várias operações herdadas da classeVector para remover elementos.
7.1. Removendo Elementos Especificados
Podemos usar o métodoremoveElement() para remover a primeira ocorrência de determinado elemento:
@Test
public void whenRemoveElementIsInvoked_thenElementIsRemoved() {
Stack intStack = new Stack();
intStack.push(5);
intStack.push(5);
intStack.removeElement(5);
assertEquals(1, intStack.size());
}
Também podemos usarremoveElementAt() para excluir elementos em um índice especificado emStack:
@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. Removendo vários elementos
Vamos dar uma olhada rápida em como remover vários elementos deStack usando a APIremoveAll() - que pegaráCollection como argumento e removerá todos os elementos correspondentes deStack:
@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());
}
Também é possível remover todos os elementos deStack usando os métodosclear() ouremoveAllElements(); ambos os métodos funcionam da mesma forma:
@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. Removendo Elementos Usando Filtro
Também podemos usar uma condição para remover elementos deStack.. Vamos ver como fazer isso usandoremoveIf(), com uma expressão de filtro como argumento:
@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. Iterando
Stack nos permite usar tanto umIteratore umListIterator. A principal diferença é que o primeiro nos permite atravessarStack em uma direção e o segundo permite fazer isso em ambas direcoes:
@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));
}
Todos osIterators retornados porStack são fail-fast.
9. API Stream
A Stack é uma coleção, o que significa que podemos usá-lo com 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. Sumário
Este tutorial foi um guia rápido para entender o JavaStack. Para saber mais sobre este tópico, consulteJavadoc.
E, como sempre, todos os exemplos de código podem ser encontradosover on Github.