1. Gambaran keseluruhan
Dalam artikel ringkas ini, kami akan memperkenalkan kelas java.util.Stack dan mula melihat bagaimana kita dapat memanfaatkannya.
Stack adalah struktur data generik yang mewakili koleksi objek LIFO (masuk terakhir, keluar pertama) yang memungkinkan untuk mendorong / memunculkan elemen dalam masa yang tetap.
Untuk pelaksanaan baru, kita harus memilih antara muka Deque dan pelaksanaannya . Deque menentukan satu set operasi LIFO yang lebih lengkap dan konsisten. Namun, kita mungkin masih perlu berurusan dengan kelas Stack , terutama dalam kod warisan, adakah penting untuk mengetahui dengan lebih baik.
2. Buat Tumpukan
Mari mulakan dengan membuat contoh kosong Stack , dengan menggunakan pembangun tanpa argumen lalai:
@Test public void whenStackIsCreated_thenItHasSizeZero() { Stack intStack = new Stack(); assertEquals(0, intStack.size()); }
Ini akan membuat Stack dengan kapasiti lalai 10. Jika jumlah elemen yang ditambahkan melebihi jumlah keseluruhan Stack , ia akan digandakan secara automatik. Namun, ukurannya tidak akan pernah menyusut setelah mengeluarkan unsur.
3. Penyegerakan untuk Stack
Stack adalah subkelas Vektor langsung ; ini bermaksud bahawa sama dengan superclassnya, ia adalah pelaksanaan yang diselaraskan .
Walau bagaimanapun, penyegerakan tidak selalu diperlukan, dalam kes sedemikian, disarankan untuk menggunakan ArrayDeque .
4. Tambahkan ke dalam Tumpukan
Mari mulakan dengan menambahkan elemen ke bahagian atas Stack , dengan kaedah push () - yang juga mengembalikan elemen yang ditambahkan:
@Test public void whenElementIsPushed_thenStackSizeIsIncreased() { Stack intStack = new Stack(); intStack.push(1); assertEquals(1, intStack.size()); }
Menggunakan push () kaedah mempunyai kesan yang sama seperti menggunakan addElement (). T dia hanya perbezaan adalah bahawa addElement () mengembalikan hasil daripada operasi, bukan elemen yang telah ditambah.
Kami juga dapat menambahkan beberapa elemen sekaligus:
@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. Dapatkan dari Stack
Seterusnya, mari kita lihat bagaimana mendapatkan dan membuang elemen terakhir dalam 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()); }
Kita juga boleh mendapatkan elemen terakhir dari taktik S tanpa mengeluarkannya:
@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. Cari Elemen dalam Tumpukan
6.1. Cari
Tumpukan membolehkan kita mencari elemendan dapatkan jarak dari atas:
@Test public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() { Stack intStack = new Stack(); intStack.push(5); intStack.push(8); assertEquals(2, intStack.search(5)); }
Hasilnya adalah indeks objek yang diberikan. Sekiranya terdapat lebih daripada satu elemen, indeks satupaling hampir dengan bahagian atas dikembalikan . Item yang berada di bahagian atas timbunan dianggap berada di kedudukan 1.
Sekiranya objek tidak dijumpai, carian () akan kembali -1.
6.2. Mendapatkan Indeks Elemen
Untuk mendapatkan indeks elemen pada taktik S , kita juga dapat menggunakan kaedah indexOf () dan lastIndexOf () :
@Test public void whenElementIsOnStack_thenIndexOfReturnsItsIndex() { Stack intStack = new Stack(); intStack.push(5); int indexOf = intStack.indexOf(5); assertEquals(0, indexOf); }
The lastIndexOf () akan sentiasa mencari indeks elemen yang paling dekat dengan bahagian atas tindanan . Ini berfungsi sama untuk mencari () - dengan perbezaan penting bahawa ia mengembalikan indeks, bukan jarak dari atas:
@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. Keluarkan Elemen dari Tumpukan
Selain daripada operasi pop () , yang digunakan untuk menghapus dan mengambil elemen, kita juga dapat menggunakan beberapa operasi yang diwarisi dari kelas Vektor untuk membuang elemen.
7.1. Mengeluarkan Elemen yang Ditentukan
Kita boleh menggunakan kaedah removeElement () untuk membuang kejadian pertama elemen yang diberikan:
@Test public void whenRemoveElementIsInvoked_thenElementIsRemoved() { Stack intStack = new Stack(); intStack.push(5); intStack.push(5); intStack.removeElement(5); assertEquals(1, intStack.size()); }
Kita juga dapat menggunakan removeElementAt () untuk menghapus elemen di bawah indeks yang ditentukan di 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. Membuang Pelbagai Unsur
Mari kita lihat bagaimana membuang pelbagai elemen dari Stack menggunakan API removeAll () - yang akan mengambil Koleksi sebagai argumen dan membuang semua elemen yang sesuai dari 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)); }
Ia juga boleh membuang semua unsur-unsur dari Stack menggunakan jelas () atau removeAllElements () kaedah ; kedua-dua kaedah tersebut berfungsi sama:
@Test public void whenRemoveAllElementsIsInvoked_thenAllElementsAreRemoved() { Stack intStack = new Stack(); intStack.push(5); intStack.push(7); intStack.removeAllElements(); assertTrue(intStack.isEmpty()); }
7.3. Mengeluarkan Elemen Menggunakan Penapis
Kita juga boleh menggunakan syarat untuk mengeluarkan elemen dari Stack. Mari lihat bagaimana melakukan ini menggunakan removeIf () , dengan ungkapan penapis sebagai argumen:
@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. Mengulangi Tumpukan
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.
Sudah tentu, anda boleh meneroka API penuh di Javadoc.
Dan, seperti biasa, semua sampel kod boleh didapati di GitHub.