Memahami Java List: Dasar, ArrayList vs LinkedList, Penggunaan

1. Pendahuluan

Pentingnya List dalam Java

Dalam pemrograman Java, “List” adalah struktur data yang sangat sering muncul. Terutama dalam situasi di mana Anda ingin mengelola banyak nilai sekaligus, List lebih fleksibel dan mudah digunakan dibandingkan array, sehingga sangat dihargai di banyak lingkungan kerja.

“List” adalah antarmuka inti dari Java Collections Framework, dan melalui berbagai kelas implementasi seperti ArrayList dan LinkedList, tersedia mekanisme yang dapat menangani berbagai situasi. Kemampuan untuk melakukan operasi seperti penambahan, penghapusan, pencarian, dan pembaruan data secara intuitif juga merupakan salah satu alasan List didukung.

Tujuan dan Target Pembaca Artikel Ini

Artikel ini akan menjelaskan dasar-dasar hingga aplikasi dari “Java List” secara sistematis dan mudah dipahami bagi pemula. Target utama pembaca adalah sebagai berikut:

  • Mereka yang baru mulai belajar Java dan merasa tidak yakin tentang cara menggunakan List.
  • Mereka yang ingin memahami dengan jelas perbedaan antara array (Array) dan List.
  • Mereka yang bingung memilih antara ArrayList dan LinkedList.
  • Mereka yang ingin meninjau dasar-dasar List untuk menggunakannya dalam pekerjaan praktis.

Setelah selesai membaca artikel ini, Anda diharapkan akan memahami dengan kuat pemikiran dasar, metode implementasi, dan operasi spesifik dari List dalam Java, serta dapat melakukan coding dengan percaya diri.

Pada bab berikutnya, kita akan mulai menjelaskan dari bagian dasar, yaitu “Apa itu List?”, secara bertahap.

2. Apa Itu List?

Gambaran Umum dan Karakteristik List

Dalam Java, “List” adalah antarmuka koleksi yang menyimpan elemen-elemen dalam urutan tertentu. Ciri terbesarnya adalah urutan penambahan elemen dipertahankan, dan elemen individual dapat diakses menggunakan indeks (dimulai dari 0).

List disediakan sebagai bagian dari Collections Framework dan memiliki fungsi-fungsi berikut:

  • Mengizinkan duplikasi elemen
  • Dapat mengambil, memperbarui, dan menghapus elemen dengan menentukan indeks
  • Jumlah elemen dapat bertambah atau berkurang secara dinamis (tidak memiliki panjang tetap seperti array)

Dengan demikian, operasi data yang fleksibel menjadi mungkin, dan sangat sering digunakan dalam pekerjaan praktis.

Perbedaan dengan Array

Dalam Java, array (seperti int[] atau String[]) juga ada sebagai cara untuk menyimpan banyak nilai, tetapi ada beberapa perbedaan dengan List.

Item PerbandinganArrayList
Perubahan Jumlah ElemenTidak Bisa (Panjang Tetap)Bisa (Dapat Bertambah/Berkurang Secara Dinamis)
Fungsi yang DisediakanOperasi Minimum (Akses Indeks, Mendapatkan Panjang)Metode Berlimpah (add, remove, contains, dll.)
TipeDapat Menangani Tipe PrimitifHanya Tipe Objek (Memerlukan Wrapper Class)
Keamanan TipeArray Diperiksa Tipe Saat KompilasiDapat Menentukan Tipe Secara Ketat dengan Generics

Dengan demikian, List adalah koleksi yang lebih fleksibel dan berfitur lengkap, dan seringkali lebih praktis daripada array dalam banyak situasi.

Antarmuka List dan Kelas Implementasinya

Saat menggunakan List dalam Java, pada dasarnya Anda mendeklarasikan variabel menggunakan antarmuka List dan membuat instance dengan kelas konkret (kelas implementasi). Kelas implementasi yang 대표的な adalah sebagai berikut:

  • ArrayList
    Struktur mirip array memungkinkan akses cepat. Kuat dalam pencarian data dan akses acak.
  • LinkedList
    Setiap elemen terhubung dengan elemen sebelumnya dan berikutnya. Penyisipan/penghapusan cepat, cocok untuk daftar yang sering mengalami operasi.
  • Vector
    Mirip dengan ArrayList, tetapi thread-safe sehingga sedikit lebih lambat. Saat ini jarang digunakan.

Secara umum, ArrayList adalah yang paling sering digunakan kecuali ada alasan khusus. Anda dapat memilih penggunaannya dengan merujuk pada perbandingan kinerja yang akan dibahas nanti, tergantung pada tujuan.

3. Cara Penggunaan Dasar List

Bab ini akan menjelaskan operasi dasar saat menggunakan List dalam Java secara bertahap. Di sini, terutama menggunakan ArrayList sebagai contoh, kami akan memperkenalkan operasi representatif dari List.

Deklarasi dan Inisialisasi List

Pertama, deklarasi dan inisialisasi dasar dari List menggunakan ArrayList.

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>();
    }
}

Umumnya, variabel dideklarasikan dengan antarmuka List dan di-instance dengan ArrayList. Tipe data yang akan disimpan (dalam contoh ini String) ditentukan menggunakan Generics.

Penambahan Elemen (add)

Untuk menambahkan elemen ke List, gunakan metode add().

fruits.add("りんご");
fruits.add("バナナ");
fruits.add("みかん");

Dengan ini, tiga elemen ditambahkan ke List secara berurutan. List mempertahankan urutan penambahan.

Pengambilan Elemen (get)

Untuk mengambil elemen pada indeks yang ditentukan, gunakan get(int index).

System.out.println(fruits.get(0)); // Akan menampilkan "りんご"

Perhatikan bahwa indeks dimulai dari 0.

Pembaruan Elemen (set)

Jika Anda ingin memperbarui elemen pada posisi tertentu, gunakan set(int index, E element).

fruits.set(1, "ぶどう"); // Elemen kedua "バナナ" digantikan dengan "ぶどう"

Penghapusan Elemen (remove)

Anda juga dapat menghapus elemen pada indeks tertentu atau elemen itu sendiri.

fruits.remove(0);           // Menghapus elemen pertama
fruits.remove("みかん");   // Menghapus "みかん" (hanya yang pertama cocok)

Pengambilan Ukuran List (size)

Jumlah elemen saat ini dapat diambil dengan metode size().

System.out.println(fruits.size()); // Mengembalikan 2, dll.

Pemeriksaan Keberadaan Elemen (contains)

Untuk memeriksa apakah elemen tertentu terkandung dalam List, gunakan contains().

if (fruits.contains("ぶどう")) {
    System.out.println("ぶどう ada");
}

Ringkasan: Daftar Operasi Dasar yang Sering Digunakan

OperasiContoh MetodePenjelasan
Penambahanadd("elemen")Ditambahkan di akhir
Pengambilanget(indeks)Mengambil referensi elemen
Pembaruanset(indeks, elemen_baru)Mengubah elemen pada posisi yang ditentukan
Penghapusanremove(indeks/elemen)Menghapus elemen yang ditentukan
Pengambilan Ukuransize()Mengambil jumlah elemen
Pemeriksaan Keberadaancontains("elemen")Memeriksa keberadaan elemen tertentu

4. Contoh Operasi List

Pada bab ini, kami akan memperkenalkan contoh operasi nyata menggunakan List dalam Java. Situasi di mana elemen dalam daftar perlu diproses secara berurutan sangat sering terjadi, dan di sini kami akan membahas metode representatif menggunakan for loop, enhanced for loop, dan Stream API.

Iterasi dengan for loop

Metode yang paling dasar adalah menggunakan for loop untuk mengambil elemen menggunakan indeks.

List<String> fruits = new ArrayList<>();
fruits.add("りんご");
fruits.add("バナナ");
fruits.add("みかん");

for (int i = 0; i < fruits.size(); i++) {
    System.out.println(fruits.get(i));
}

Metode ini memungkinkan kontrol detail menggunakan indeks. Misalnya, efektif ketika Anda hanya ingin memproses elemen pada posisi genap.

Iterasi dengan enhanced for loop (for-each)

Jika Anda ingin memproses semua elemen secara berurutan tanpa mempedulikan indeks, enhanced for loop sangat nyaman.

for (String fruit : fruits) {
    System.out.println(fruit);
}

Penulisannya sederhana dan mudah dibaca, menjadikannya salah satu metode yang paling sering digunakan. Untuk pemrosesan yang sederhana, metode ini sudah cukup.

Iterasi dengan Lambda Expression dan Stream API

Sejak Java 8, cara penulisan menggunakan Stream API dan lambda expression juga dimungkinkan.

fruits.stream().forEach(fruit -> System.out.println(fruit));

Keunggulan notasi ini adalah kemampuannya untuk menggabungkan beberapa proses secara berantai. Misalnya, memfilter dengan kondisi tertentu sebelum mencetak dapat dilakukan dengan mudah.

fruits.stream()
      .filter(fruit -> fruit.contains("ん"))
      .forEach(System.out::println);

Contoh ini akan mencetak hanya buah-buahan yang mengandung karakter “ん”. Metode ini sangat direkomendasikan bagi mereka yang ingin terbiasa dengan coding gaya fungsional.

Memilih Metode Penggunaan

MetodeKeunggulanCocok untuk Situasi
for loop BiasaMemungkinkan kontrol indeksPemrosesan yang memerlukan nomor elemen
enhanced for loopPenulisan sederhana dan mudah dibacaPemrosesan iterasi sederhana
Stream APIKuat untuk pemrosesan bersyarat dan berantaiKetika ingin menggabungkan filter, map, dan agregasi

5. Perbedaan dan Penggunaan ArrayList dan LinkedList

Sebagai kelas implementasi representatif dari antarmuka List Java, terdapat ArrayList dan LinkedList. Keduanya dapat digunakan sebagai List secara serupa, tetapi penting untuk memilih penggunaannya dengan tepat di situasi yang sesuai karena perbedaan dalam struktur internal dan karakteristik kinerja.

Karakteristik dan Kasus Penggunaan yang Tepat untuk ArrayList

ArrayList secara internal menggunakan array dinamis (array dengan ukuran variabel).

Karakteristik Utama:

  • Sangat cepat untuk akses acak (akses dengan indeks)
  • Penambahan elemen cepat jika di akhir list (rata-rata O(1))
  • Penyisipan/penghapusan di tengah menjadi lambat (O(n))

Cocok untuk Situasi:

  • Situasi yang sering melakukan pencarian (get())
  • Situasi di mana jumlah elemen dapat diprediksi sampai batas tertentu sebelumnya
  • Pemrosesan yang jarang melakukan penambahan/penghapusan elemen, berorientasi baca
List<String> list = new ArrayList<>();

Karakteristik dan Kasus Penggunaan yang Tepat untuk LinkedList

LinkedList diimplementasikan dengan struktur daftar terhubung ganda.

Karakteristik Utama:

  • Penambahan/penghapusan elemen cepat (terutama di awal atau akhir)
  • Akses acak (get(index)) lambat (O(n))
  • Konsumsi memori sedikit lebih banyak daripada ArrayList

Cocok untuk Situasi:

  • Situasi yang sering melakukan penyisipan/penghapusan elemen (terutama di awal atau tengah)
  • Ketika ingin menggunakannya seperti Queue atau Stack
  • Ketika berorientasi iterasi dan akses indeks tidak diperlukan
List<String> list = new LinkedList<>();

Perbandingan Kinerja

Tabel di bawah ini menunjukkan kompleksitas komputasi teoritis (notasi Big O) untuk operasi yang sering digunakan.

OperasiArrayListLinkedList
get(int index)O(1)O(n)
add(E e) (di akhir)O(1)O(1)
add(int index, E e)O(n)O(n)
remove(int index)O(n)O(n)
IterasiO(n)O(n)

※ Waktu pemrosesan aktual juga dipengaruhi oleh ukuran data, optimasi JVM, dll.

Poin Penting dalam Memilih Penggunaan di Praktik

  • Jika “mengelola data sebagai daftar dan mengaksesnya dengan indeks”, gunakan ArrayList
  • Jika “sering terjadi penyisipan/penghapusan di awal/tengah”, gunakan LinkedList
  • Dalam pemrosesan yang kritis terhadap kinerja, pastikan untuk melakukan benchmark dan validasi

6. Cara Penggunaan List Tingkat Lanjut

Di sini, kami akan memperkenalkan teknik tingkat lanjut untuk menggunakan List Java dengan lebih nyaman. List tidak hanya berfungsi sebagai kumpulan data, tetapi juga dapat melakukan berbagai pemrosesan melalui sort, shuffle, filter, transform, dll.

Sortir List (Collections.sort)

Menggunakan Collections.sort(), elemen dalam List dapat diurutkan secara ascending (naik). Elemen harus mengimplementasikan antarmuka Comparable.

import java.util.*;

List<String> fruits = new ArrayList<>();
fruits.add("バナナ");
fruits.add("りんご");
fruits.add("みかん");

Collections.sort(fruits);

System.out.println(fruits); // [みかん, りんご, バナナ]

Ketika menyortir dengan urutan kustom (Menggunakan Comparator)

fruits.sort(Comparator.reverseOrder()); // Mengurutkan secara descending

Mengacak List (Collections.shuffle)

Untuk mengacak urutan elemen secara acak, Anda dapat menggunakan Collections.shuffle().

Collections.shuffle(fruits);
System.out.println(fruits); // [バナナ, みかん, りんご] (contoh)

Berguna saat Anda membutuhkan tumpukan kartu dalam game atau urutan tampilan yang acak.

Filtering dengan Stream API (filter)

Sejak Java 8, menggunakan Stream, pemrosesan untuk mengekstrak hanya elemen yang memenuhi kondisi tertentu dapat ditulis secara ringkas.

List<String> filtered = fruits.stream()
    .filter(fruit -> fruit.contains("ん"))
    .collect(Collectors.toList());

System.out.println(filtered); // [みかん, りんご]

Transformasi dengan Stream API (map)

Jika Anda ingin mengubah elemen ke format lain, gunakan map().

List<Integer> lengths = fruits.stream()
    .map(String::length)
    .collect(Collectors.toList());

System.out.println(lengths); // Jumlah karakter nama setiap buah [3, 3, 2] dst.

map() adalah alat yang kuat dalam konversi format data dan preprocessing.

Ringkasan Operasi Tingkat Lanjut

OperasiContoh PenggunaanKegunaan Utama
SortirCollections.sort(list)Mengurutkan secara ascending
MengacakCollections.shuffle(list)Mengacak urutan elemen
Filterstream().filter(...).collect()Mengekstrak hanya elemen yang memenuhi kondisi
Transformasistream().map(...).collect()Mengubah tipe atau nilai elemen

7. Kesalahan Umum dan Cara Mengatasinya

Saat menangani List dalam Java, salah satu hal yang paling sering membuat pemula tersandung adalah “Exception (Error)”. Di sini, kami akan secara spesifik menjelaskan kesalahan representatif yang sering terjadi dalam praktik, serta penyebab dan cara mengatasinya.

IndexOutOfBoundsException (Error Indeks di Luar Batas)

Penyebab:

Terjadi ketika mencoba mengakses indeks yang tidak ada.

List<String> list = new ArrayList<>();
list.add("りんご");

System.out.println(list.get(1)); // Error: Index 1 out of bounds

Cara Mengatasi:

Periksa ukuran sebelum mengakses, atau kontrol dengan percabangan kondisi apakah indeks valid.

if (list.size() > 1) {
    System.out.println(list.get(1));
}

NullPointerException

Penyebab:

Terjadi ketika memanggil metode pada List itu sendiri atau elemen List yang bernilai null.

List<String> list = null;
list.add("りんご"); // NullPointerException terjadi

Cara Mengatasi:

Pastikan variabel tidak null sebelumnya, atau gunakan Optional, dll.

if (list != null) {
    list.add("りんご");
}

Atau, perhatikan agar tidak lupa melakukan inisialisasi:

List<String> list = new ArrayList<>(); // Inisialisasi yang benar

ConcurrentModificationException

Penyebab:

Terjadi ketika List diubah secara langsung saat melakukan iterasi dengan for-each loop atau Iterator.

for (String fruit : list) {
    if (fruit.equals("バナナ")) {
        list.remove(fruit); // ConcurrentModificationException
    }
}

Cara Mengatasi:

Gunakan Iterator untuk menghapus dengan aman, atau gunakan metode seperti removeIf().

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (it.next().equals("バナナ")) {
        it.remove(); // Dihapus dengan aman
    }
}

Atau, sejak Java 8, secara ringkas:

list.removeIf(fruit -> fruit.equals("バナナ"));

Poin Perhatian Lainnya

  • Konfirmasi bahwa List tidak null
  • Sangat sering terjadi kasus di mana variabel hanya dideklarasikan tetapi tidak digunakan. Inisialisasi adalah keharusan.
  • Pemahaman bahwa indeks dimulai dari 0
  • Seringkali pemula salah paham bahwa “elemen pertama adalah indeks 1”.

Ringkasan Penanganan Error

Nama ErrorPenyebab UtamaContoh Cara Mengatasi
IndexOutOfBoundsExceptionAkses ke indeks yang tidak adaPeriksa panjang dengan size()
NullPointerExceptionList atau elemen bernilai nullJangan lupa inisialisasi, lakukan null check
ConcurrentModificationExceptionMengubah List secara langsung saat iterasiOperasi dengan Iterator atau manfaatkan removeIf()

8. Ringkasan

Meninjau Kembali Dasar-dasar Java List

Dalam artikel ini, kami telah menjelaskan dasar-dasar hingga aplikasi dari List dalam Java secara bertahap. List adalah salah satu koleksi yang paling sering digunakan dalam Java, dan merupakan alat penting untuk menangani data secara fleksibel.

Pertama, setelah memahami apa itu List, kami mempelajari poin-poin berikut:

  • List adalah koleksi berurutan dan mengizinkan duplikasi, memungkinkan operasi indeks
  • Ada kelas implementasi representatif seperti ArrayList dan LinkedList, dengan karakteristik dan kegunaan yang berbeda
  • Operasi data dapat dilakukan secara bebas dengan menguasai operasi dasar (penambahan, pengambilan, pembaruan, penghapusan, pencarian)
  • Pemrosesan iterasi sesuai situasi seperti for loop, enhanced for loop, dan Stream API
  • Juga mendukung pemrosesan tingkat lanjut seperti sort, filter, dan transform
  • Memahami error umum serta penyebab dan cara mengatasinya dapat mencegah masalah sejak dini

Memilih Penggunaan ArrayList dan LinkedList

Penting untuk memilih implementasi List yang tepat sesuai dengan isi pemrosesan dan volume data. Pertimbangan berikut dapat menjadi panduan:

  • ArrayList: Sering terjadi akses acak, dan pemrosesan berorientasi baca
  • LinkedList: Sering terjadi penyisipan/penghapusan, dan urutan akses penting

Untuk Pembelajaran Selanjutnya

List hanyalah “pintu masuk” ke Collections dalam Java. Untuk menangani struktur data dan utilitas yang lebih canggih, akan baik untuk memperdalam pemahaman tentang kelas/fungsi berikut:

  • Set・Map: Manajemen elemen unik, struktur pasangan kunci-nilai
  • Collections utility class: Sortir, mendapatkan nilai minimum/maksimum, dll.
  • Pemanfaatan Stream API: Pengenalan pemrograman fungsional
  • Pemahaman Generics: Operasi koleksi yang tipe-aman

Menguasai dasar-dasar List akan membuat seluruh pemrograman Java menjadi jauh lebih mudah.

Pertanyaan yang Sering Diajukan (FAQ)

Kami telah merangkum poin-poin yang sering membuat pemula bingung terkait Java List. Kami telah memilih konten yang sering ditemui dalam praktik.

Q1. Apa perbedaan antara Java List dan array (Array)?

A. Array memiliki jumlah elemen tetap dan perlu ditentukan ukurannya saat deklarasi. Di sisi lain, List memiliki ukuran yang variabel, memungkinkan penambahan dan penghapusan elemen secara fleksibel. Selain itu, List dilengkapi dengan banyak metode yang nyaman (add, remove, contains, dll.), dan juga lebih unggul dalam hal keterbacaan dan pemeliharaan.

Q2. Saya harus menggunakan ArrayList atau LinkedList?

A. ArrayList lebih cocok jika sering terjadi akses acak (pengambilan dengan menentukan indeks). LinkedList lebih cocok jika sering terjadi penyisipan/penghapusan elemen. Jika ragu, umumnya disarankan untuk memulai dengan ArrayList.

Q3. Bisakah List menyimpan tipe primitif (int, double, dll.)?

A. Tidak secara langsung. Karena List Java hanya menangani tipe objek, untuk tipe primitif seperti int, Anda perlu menggunakan wrapper class yang sesuai (Integer, Double, dll.).

List<Integer> numbers = new ArrayList<>();
numbers.add(10); // Auto-boxing dan disimpan sebagai tipe Integer

Q4. Saya ingin mengurutkan elemen List, bagaimana caranya?

A. Anda dapat mengurutkan secara ascending menggunakan Collections.sort(list). Juga, jika Anda ingin mengurutkan dengan urutan kustom, Anda dapat menentukan Comparator untuk mengurutkan dengan bebas.

Q5. Bagaimana cara mengelola elemen tanpa duplikasi?

A. List adalah koleksi yang mengizinkan duplikasi. Jika Anda ingin menghindari duplikasi, pertimbangkan penggunaan Set (contoh: HashSet). Namun, perlu diperhatikan bahwa urutan tidak dijamin. Jika Anda ingin menghilangkan duplikasi sambil tetap menggunakan List, pemrosesan Stream berikut juga memungkinkan.

List<String> distinctList = list.stream()
    .distinct()
    .collect(Collectors.toList());

Q6. Bagaimana cara menghapus semua isi List?

A. Menggunakan metode clear() akan menghapus semua elemen List.

list.clear();

Q7. Operasi apa yang paling sering digunakan dalam List?

A. Operasi yang paling sering digunakan di lapangan adalah add (penambahan), get (pengambilan), remove (penghapusan), dan size (pengambilan ukuran). Dengan menguasai ini, pemrosesan dasar hampir seluruhnya tercakup.