Java Collections Framework (JCF) adalah serangkaian kelas dan interface yang menyediakan struktur data siap pakai. Berbeda dengan array biasa yang ukurannya tetap, koleksi Java bisa tumbuh dan menyusut secara dinamis. Di artikel ini kita akan mempelajari koleksi yang paling sering digunakan dalam pengembangan aplikasi Java nyata.
Array vs ArrayList
// Array: ukuran tetap, tidak bisa diubah setelah dibuat
int[] nilai_array = {85, 92, 78, 95, 88};
// nilai_array hanya bisa menampung 5 elemen, tidak bisa ditambah
// ArrayList: ukuran dinamis, bisa tambah/hapus elemen
import java.util.ArrayList;
ArrayList<Integer> nilai_list = new ArrayList<>();
nilai_list.add(85);
nilai_list.add(92);
nilai_list.add(78);
System.out.println(nilai_list.size()); // Output: 3
nilai_list.add(95); // Bisa terus ditambah
System.out.println(nilai_list.size()); // Output: 4
Catatan Penting: Autoboxing
Java memisahkan tipe primitif (int, double) dan objek (Integer, Double). ArrayList hanya bisa menyimpan objek, bukan primitif. Java otomatis mengkonversi ini — disebut autoboxing:
ArrayList<Integer> angka = new ArrayList<>();
angka.add(42); // autoboxing: int 42 → Integer(42) otomatis
int nilai = angka.get(0); // unboxing: Integer(42) → int 42 otomatis
// Ini mengapa ArrayList<int> tidak valid, harus ArrayList<Integer>
ArrayList — Koleksi Dinamis Paling Umum
import java.util.ArrayList;
import java.util.Collections;
public class ContohArrayList {
public static void main(String[] args) {
ArrayList<String> kota = new ArrayList<>();
// Menambahkan elemen
kota.add("Jakarta");
kota.add("Surabaya");
kota.add("Bandung");
kota.add(1, "Yogyakarta"); // Insert di indeks 1
// Akses dan informasi
System.out.println(kota.get(0)); // Output: Jakarta
System.out.println(kota.size()); // Output: 4
System.out.println(kota.contains("Bandung")); // Output: true
System.out.println(kota.indexOf("Surabaya")); // Output: 2
// Hapus elemen
kota.remove("Bandung"); // Hapus berdasarkan nilai
kota.remove(0); // Hapus berdasarkan indeks
// Iterasi
for (String k : kota) {
System.out.println("- " + k);
}
// Urutkan
Collections.sort(kota);
System.out.println(kota);
// Output: [Surabaya, Yogyakarta]
}
}
HashMap — Penyimpanan Key-Value
import java.util.HashMap;
import java.util.Map;
public class ContohHashMap {
public static void main(String[] args) {
HashMap<String, Integer> populasi = new HashMap<>();
// Menambahkan data
populasi.put("Jakarta", 10_560_000);
populasi.put("Surabaya", 2_874_000);
populasi.put("Bandung", 2_444_000);
// Akses nilai
System.out.println(populasi.get("Jakarta"));
// Output: 10560000
// Akses aman (tidak null pointer jika key tidak ada)
int pop_bali = populasi.getOrDefault("Bali", 0);
System.out.println("Populasi Bali: " + pop_bali);
// Output: Populasi Bali: 0
// Cek keberadaan key
System.out.println(populasi.containsKey("Surabaya")); // Output: true
System.out.println(populasi.containsValue(0)); // Output: false
// Update nilai
populasi.put("Jakarta", 10_600_000); // Overwrite existing key
// Iterasi semua pasangan key-value
for (Map.Entry<String, Integer> entry : populasi.entrySet()) {
System.out.printf("%s: %,d jiwa%n", entry.getKey(), entry.getValue());
}
// Ukuran dan penghapusan
System.out.println("Jumlah kota: " + populasi.size()); // Output: 3
populasi.remove("Bandung");
}
}
Koleksi Lainnya
LinkedList — Untuk Operasi Insert/Delete Sering
import java.util.LinkedList;
LinkedList<String> antrian_pesanan = new LinkedList<>();
antrian_pesanan.addLast("Pesanan #001"); // Tambah di belakang
antrian_pesanan.addLast("Pesanan #002");
antrian_pesanan.addFirst("PRIORITAS #999"); // Tambah di depan
System.out.println(antrian_pesanan.removeFirst()); // Output: PRIORITAS #999
System.out.println(antrian_pesanan.peek()); // Output: Pesanan #001 (tidak hapus)
HashSet — Koleksi Unik Tanpa Duplikat
import java.util.HashSet;
HashSet<String> tag = new HashSet<>();
tag.add("java");
tag.add("pemrograman");
tag.add("java"); // Duplikat — tidak ditambahkan!
tag.add("backend");
System.out.println(tag.size()); // Output: 3 (bukan 4)
System.out.println(tag.contains("java")); // Output: true
Kelas Utilitas Collections
import java.util.Collections;
ArrayList<Integer> nilai = new ArrayList<>();
nilai.add(85); nilai.add(92); nilai.add(78); nilai.add(95); nilai.add(88);
// Operasi umum
Collections.sort(nilai); // Urutkan ascending
Collections.reverse(nilai); // Balik urutan
Collections.shuffle(nilai); // Acak
System.out.println(Collections.max(nilai)); // Nilai terbesar
System.out.println(Collections.min(nilai)); // Nilai terkecil
System.out.println(Collections.frequency(nilai, 85)); // Berapa kali 85 muncul
// Buat koleksi yang tidak bisa diubah
List<String> tidak_bisa_diubah = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList("Java", "Python", "C++"))
);
Contoh Nyata: Sistem Inventaris Toko
import java.util.*;
public class Inventaris {
public static void main(String[] args) {
// Daftar produk dengan stok
Map<String, Integer> stok = new HashMap<>();
stok.put("Laptop", 10);
stok.put("Mouse", 50);
stok.put("Keyboard", 30);
stok.put("Monitor", 15);
stok.put("Headset", 25);
// Produk dengan stok di bawah 20
System.out.println("=== Stok Menipis ===");
List<String> perlu_restock = new ArrayList<>();
for (Map.Entry<String, Integer> entry : stok.entrySet()) {
if (entry.getValue() < 20) {
perlu_restock.add(entry.getKey());
}
}
Collections.sort(perlu_restock);
for (String produk : perlu_restock) {
System.out.printf("%-10s : %d unit%n", produk, stok.get(produk));
}
// Output:
// Laptop : 10 unit
// Monitor : 15 unit
}
}
Pertanyaan yang Sering Diajukan
Mengapa Java menggunakan Integer bukan int di dalam koleksi?
Java Collections Framework dirancang untuk bekerja dengan objek (reference types). Tipe primitif (int, double, dll.) bukan objek di Java. Integer, Double, Boolean adalah kelas wrapper yang membungkus primitif dalam objek. Java melakukan autoboxing (konversi otomatis primitif → wrapper) sehingga kamu bisa menulis list.add(42) dan Java otomatis mengkonversinya ke Integer(42).
Kapan menggunakan HashMap vs LinkedHashMap vs TreeMap?
HashMap adalah pilihan default — pencarian O(1) rata-rata tapi tidak ada jaminan urutan. LinkedHashMap mempertahankan urutan insersi — cocok jika urutan penting. TreeMap menyimpan key dalam urutan terurut — cocok untuk kasus di mana kamu butuh iterasi yang terurut tapi lebih lambat (O(log n)).
Apa perbedaan ArrayList dan LinkedList secara performa?
ArrayList menggunakan array internal — akses acak O(1) tapi insert/delete di tengah O(n). LinkedList menggunakan linked list — insert/delete di awal/akhir O(1) tapi akses acak O(n). Gunakan ArrayList untuk akses banyak, LinkedList untuk insert/delete sering di awal atau tengah.
Apakah Collections Framework Java lebih baik dari array biasa?
Untuk kebanyakan kasus: ya. Array lebih cepat dan hemat memori untuk kasus di mana ukuran tetap. Tapi Collections Framework memberikan fleksibilitas, method bawaan (sort, search), dan keamanan tipe generic. Dalam pengembangan aplikasi Enterprise (Spring Boot, Android), penggunaan ArrayList dan HashMap jauh lebih umum daripada array biasa.
Kesimpulan
| Koleksi | Karakteristik | Kapan Digunakan |
|---|---|---|
ArrayList<T> | Dinamis, akses cepat | Koleksi umum (default) |
HashMap<K,V> | Key-value, O(1) lookup | Pencarian berdasarkan key |
LinkedList<T> | Insert/delete cepat | Antrian, operasi sering di ujung |
HashSet<T> | Tanpa duplikat | Koleksi unik |
Collections | Utility methods | Sort, shuffle, min, max |
Artikel sebelumnya: Method di Java — cara membuat method di Java.
Langkah selanjutnya: Class dan Object di Java — dasar pemrograman berorientasi objek di Java.