Collections Framework adalah kumpulan interface dan kelas di package java.util yang menjadi tempat program Java menampung banyak objek sekaligus. Topik ini memetakan hierarkinya dari Iterable sampai Map, menunjukkan kontrak bersama Collection, lalu menutup dengan tabel pemilihan implementasi untuk tiap kebutuhan. Setelah menyusulinya, nama seperti ArrayList, HashSet, dan HashMap akan punya tempat yang jelas dalam peta besar itu.
Gambar besar Collections Framework#
Framework ini terdiri atas tiga lapis yang saling melengkapi. Lapis pertama adalah interface, yaitu kontrak yang menyatakan apa yang bisa dilakukan terhadap sebuah koleksi (collection), misalnya menambah, mencari, dan menghapus elemen. Lapis kedua adalah kelas implementasi, seperti ArrayList dan HashMap, yang menyatakan bagaimana kontrak itu dipenuhi dengan struktur data tertentu. Lapis ketiga berupa algoritma siap pakai di kelas utilitas Collections, misalnya pengurutan dan pembalikan. Ketiganya ada di package java.util sejak Java 1.2, sehingga kode yang memakainya tidak bergantung pada library tambahan apa pun.
Kerangka lapisan tersebut terlihat pada deklarasi-deklarasi berikut, yang semuanya diambil dari bentuk paling sederhana interface terkait.
// tidak-dijalankan
interface Iterable<E> // bisa disusuri dengan for-each
interface Collection<E> extends Iterable<E> // add, remove, size, contains
interface List<E> extends Collection<E> // berurutan, punya indeks
interface Set<E> extends Collection<E> // tanpa duplikat
interface Queue<E> extends Collection<E> // antrean (queue), serah-terima di ujung
interface Map<K, V> // pasangan kunci-nilai, di luar CollectionDeklarasi itu memperlihatkan pola yang konsisten. List, Set, dan Queue mewarisi seluruh kontrak Collection, lalu masing-masing menambah aturan dan metode yang khas. Map sengaja berdiri sendiri karena bentuk datanya berbeda, sebagaimana dijelaskan pada bagian tersendiri di bawah.
Hierarki interface dari Iterable sampai Queue#
Ujung atas hierarki adalah Iterable, interface paling minim yang hanya menuntut satu kemampuan, yaitu menghasilkan Iterator untuk menyusuri isinya. Kemampuan sekecil ini yang membuat semua koleksi bisa dipakai bersama perulangan for-each. Di bawahnya, Collection mewarisi Iterable dan menambah operasi dasar yang dipakai hampir setiap hari, seperti add, remove, size, contains, dan isEmpty. Tiga interface turunannya kemudian memecah kebutuhan praktis menjadi tiga ragam.
Tiga cabang itu dibedakan oleh aturan yang paling menentukan. List menjaga urutan penyimpanan dan mengizinkan elemen sama muncul lebih dari sekali, sehingga cocok untuk daftar belanja atau riwayat pencarian. Set menolak duplikat dan tidak menjanjikan urutan apa pun, sehingga cocok untuk penanda unik seperti kata kunci artikel. Queue memakai kaidah serah-terima di ujung, elemen masuk dari satu sisi dan keluar dari sisi lain, sehingga cocok untuk antrean pekerjaan. Setiap cabang punya beberapa implementasi yang membedakan struktur data di baliknya, dan pemilihan itu menjadi inti pembahasan tiap interface.
Collection sebagai kontrak bersama#
Kekuatan lapis Collection terasa saat kode ditulis terhadap kontraknya, bukan terhadap kelas konkretnya. Variabel bertipe Collection<String> dapat menampung ArrayList maupun HashSet tanpa mengubah satu baris pun pada kode yang memakainya. Program berikut membandingkan kedua implementasi itu lewat variabel bertipe sama.
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DemoCollection {
public static void main(String[] args) {
Collection<String> antreanCetak = new ArrayList<>();
antreanCetak.add("laporan.pdf");
antreanCetak.add("poster.png");
antreanCetak.add("laporan.pdf");
Collection<String> tagUnik = new HashSet<>();
tagUnik.add("java");
tagUnik.add("collections");
tagUnik.add("java");
System.out.println("jumlah elemen antrean : " + antreanCetak.size());
System.out.println("jumlah elemen set : " + tagUnik.size());
System.out.println("ada poster.png? : " + antreanCetak.contains("poster.png"));
antreanCetak.remove("poster.png");
System.out.println("sesudah remove : " + antreanCetak);
for (String tanda : tagUnik) {
System.out.println("tag: " + tanda);
}
}
}jumlah elemen antrean : 3
jumlah elemen set : 2
ada poster.png? : true
sesudah remove : [laporan.pdf, laporan.pdf]
tag: java
tag: collectionsCara menjalankannya cukup satu perintah, sebagaimana kebiasaan sepanjang jalur ini.
# berada di folder tempat DemoCollection.java disimpan
java DemoCollection.javajumlah elemen antrean : 3
jumlah elemen set : 2
ada poster.png? : true
sesudah remove : [laporan.pdf, laporan.pdf]
tag: java
tag: collectionsKeluarannya menegaskan perbedaan kontrak antarimplementasi. ArrayList menerima “laporan.pdf” dua kali sehingga ukurannya tiga, sedangkan HashSet menolak duplikat kedua sehingga ukurannya hanya dua. Metode add, remove, size, dan contains dipanggil dengan bentuk sama pada keduanya karena semuanya milik kontrak Collection, sedangkan perbedaan urutan cetak pada HashSet adalah konsekuensi struktur internalnya yang tidak menjanjikan urutan.
Pola yang diperlihatkan program ini adalah kebiasaan yang dipegang sepanjang modul, yaitu variabel diberi tipe interface dan objeknya dibuat lewat kelas implementasi. Pembaca kode jadi langsung tahu operasi apa saja yang boleh dipanggil tanpa perlu membuka kelas konkret, dan pergantian implementasi tidak merambat ke pemakainya. Kontrak yang sama juga membuat satu metode utilitas bisa menerima koleksi apa pun lewat parameter bertipe Collection.
Posisi Map yang terpisah#
Map tidak menurunkan Collection, dan alasannya bersifat teknis, bukan sejarah semata. Collection mengelola kumpulan elemen tunggal, sedangkan Map mengelola pasangan kunci-nilai (key-value), sehingga pertanyaan “apakah elemen ini ada” tidak lagi cukup, karena Map juga ditanya “apa nilai untuk kunci ini”. Metode utamanya pun berbeda bentuk, yaitu put(K, V) untuk menyimpan dan get(K) untuk membaca, bukan add(E) dan contains(E).
Meski berdiri sendiri, Map tetap bisa dilihat sebagai koleksi melalui tiga metode yang mengembalikan Collection. Metode keySet() memberi himpunan kunci, values() memberi kumpulan nilai, dan entrySet() memberi kumpulan pasangan lengkap. Lewat tampilan-tampilan (view) itu, seluruh kebiasaan Collection, termasuk for-each, tetap berlaku terhadap isi Map. Pemisahan ini juga menjadi alasan modul khusus untuk Map, karena operasi, tampilan, dan jebakannya cukup berbeda dari koleksi elemen tunggal.
// tidak-dijalankan
for (String kunci : stokGudang.keySet()) {
System.out.println("kunci: " + kunci);
}
for (Integer jumlah : stokGudang.values()) {
System.out.println("nilai: " + jumlah);
}Memilih implementasi#
Interface menentukan apa yang bisa dilakukan, sedangkan implementasi menentukan seberapa cepat dan dengan struktur data apa. Tabel berikut merangkum pasangan yang paling sering dipakai beserta alasan memilihnya.
| Interface | Kebutuhan | Implementasi lazim |
|---|---|---|
List | urutan penting, akses lewat indeks | ArrayList |
List | sisip dan hapus sering terjadi di kedua ujung | LinkedList |
Set | keunikan penting, urutan tidak | HashSet |
Set | urutan penyimpanan perlu dipertahankan | LinkedHashSet |
Set | isi harus selalu terurut | TreeSet |
Queue/Deque | antrean biasa atau tumpukan | ArrayDeque |
Queue | elemen keluar berdasar prioritas | PriorityQueue |
Map | pencarian kunci-nilai tercepat | HashMap |
Map | kunci selalu terurut | TreeMap |
Tabel di atas bukan daftar untuk dihafal, melainkan titik awal. Detail pertukarannya, misalnya mengapa ArrayList hampir selalu menang atas LinkedList, dibedah di topik-topik masing-masing interface.
Kesalahan umum#
- Menganggap
Mapadalah bagian dariCollection. Pemanggilanmap.add(x)tidak ada dan kompilasi gagal. Gunakanput(kunci, nilai)untuk menyimpan, atau ambilkeySet(),values(), danentrySet()bila ingin memperlakukan isinya sebagai koleksi. - Mendeklarasikan variabel dengan tipe konkret. Variabel bertipe
ArrayList<String>mengunci kode pada satu implementasi, sehingga perubahan struktur data menular ke banyak baris. Tipekan variabelnya dengan interface. - Bergantung pada urutan
HashSetatauHashMap. Urutan itu hasil struktur internal dan tidak dijanjikan spesifikasi, sehingga bisa berbeda antarversi JVM. PilihLinkedHashSet,TreeSet, atauLinkedHashMapbila urutan memang penting. - Memakai array untuk semua hal semata-mata karena sudah dikenal. Array berukuran tetap, sedangkan kebutuhan “jumlah datanya bertambah pelan-pelan” adalah ranah
List, yang ukurannya menyesuaikan sendiri. - Menulis kode terhadap kelas konkret di seluruh program. Tipe konkret di parameter metode memaksa pemanggil menyediakan implementasi tertentu. Tipekan parameter dan nilai kembali dengan interface agar aturan itu longgar dari awal.
Ringkasan#
- Collections Framework tersusun atas interface sebagai kontrak, kelas implementasi sebagai struktur data, dan kelas
Collectionssebagai tempat algoritma siap pakai. Iterablemenjamin for-each,Collectionmenambah operasi dasar, laluList,Set, danQueuemewarisinya dengan aturan masing-masing.Mapberdiri di luarCollectionkarena berisi pasangan kunci-nilai, dan tetap bisa disusuri lewatkeySet(),values(), sertaentrySet().- Pemilihan implementasi adalah keputusan struktur data, dan variabel sebaiknya tetap dideklarasikan dengan tipe interface.
Referensi#
- The Collections Framework (The Java Tutorials) — Oracle — pengantar resmi arsitektur collections beserta pembagian interface, implementasi, dan algoritma.
- Interface Collection — Oracle Java SE 21
— daftar lengkap metode kontrak
Collectiondan syarat-syaratnya. - Interface Iterable — Oracle Java SE 21 — kontrak dasar yang membuat koleksi dapat disusuri for-each.