Bab.8 Framework
Koleksi JAVA
Tujuan Instruksional
|
|
·
Mendeskripsikan hirarki JAVA Collections
Framework (JCF).
·
Menggunakan metode-metode umum yang
didefinisikan di dalam antarmuka Collection
untuk mengeporasikan himpunan (set) dan daftar (list).
·
Menggunakan antarmuka Iterator.
·
Menggunakan loop for-each untuk
menyederhanakan koleksi.
·
Mengeksplorasi bagaimana dan kapan menggunakan
HashSet, LinkedHashSet, atau TreeSet.
·
Membandingkan elemen menggunakan antarmuka Comparable dan antarmuka Comparator.
·
Mengeksplorasi bagaimana dan kapan menggunakan
ArrayList atau LinkedList untuk menyimpan elemen.
·
Menggunakan metode-metode utilitas statik di
dalam kelas Collections untuk
mengurutkan, mencari, mengacak list, dan menemukan elemen terbesar dan
terkecil di dalam koleksi.
|
·
Membandingkan kinerja set dan list.
·
Membedakan antara Vector dan ArrayList
dan untuk menggunakan kelas Stack
untuk menciptakan tumpukan.
·
Mengeksplorasi relasi di antara Collection, Queue, LinkedList, dan
PriorityQueue dan untuk
menciptakan antrian menggunakan kelas PriorityQueue.
·
Mengetahui perbedaan antara Collection dan Map dan menjelaskan kapan dan bagaimana menggunakan HashMap, LinkedHashMap, dan TreeMap
untuk menyimpan nilai-nilai yang berkaitan dengan kunci.
|
8.1
Introduksi
Struktur data merupakan koleksi data yang
diorganisasi dengan gaya tertentu. Struktur tidak hanya menyimpan data tetapi
juga mendukung operasi-operasi untuk mengakses dan memanipulasi data. Anda
telah belajar tentang ArrayList,
yang merupakan suatu struktur data untuk menyimpan elemen-elemen di dalam suatu
list atau daftar atau senarai. JAVA menyediakan beberapa struktur data tambahan
yang dapat digunakan untuk mengorganisasi dan memanipulasi data. secara
efisien. Struktur-struktur data tersebut dikenal dengan framework koleksi JAVA
(JCF, JAVA Collections Framework).
Dalam pemikiran berorientasi-objek, suatu
struktur data, yang juga dikenal dengan kontainer, adalah suatu objek yang bisa
menyimpan objek lain, yang dikenal dengan data atau elemen. Beberapa pihak
menyebut struktur data sebagai objek kontainer. Mendefinisikan struktur data
sama dengan mendefinisikan kelas. Kelas untuk suatu struktur data harus
menggunakan bidang-bidang data untuk menyimpan data dan menyediakan beberapa
metode untuk mendukung operasi-operasi seperti pencarian, penyisipan, dan
penghapusan. Menciptakan suatu struktur data sama dengan menciptakan suatu
instans dari kelas. Anda bisa menerapkan metode-metode terhadap instans
tersebut untuk memanipulasi struktur data, seperti menyisipkan suatu elemen ke
atau menghapus suatu elemen dari struktur data.
JCF mendukung dua jenis kontainer:
·
Satu untuk menyimpan sekoleksi
elemen, yang dikenal dengan koleksi.
·
Lainnya untuk menyimpan pasangan
kunci/nilai, yang disebut dengan peta.
Peta atau map merupakan struktur data yang
efisien untuk melakukan pencarian cepat suatu elemen menggunakan kunci. Anda
akan dikenalkan tentang peta pada bab ini. Sekarang, akan didiskusikan terlebih
dahulu tentang koleksi.
8.2
Koleksi
JCF
mendukung tiga koleksi utama: Set, List, dan Queue. Suatu instans dari Set
menyimpan sekelompok elemen non-duplikat. Suatu instans dari List menyimpan sekumpulan elemen yang
terurut. Suatu instans dari Queue
menyimpan objek-objek yang diproses dengan gaya FIFO (first-in, first-out). Fitur-fitur umum koleksi ini didefinisikan di dalam beberapa
antarmuka, dan implementasinya disediakan di dalam kelas-kelas konkrit, seperti
tertampil pada Gambar 8.2.
Gambar 8.1 Koleksi merupakan suatu kontainer yang memuat
objek-objek
8.3
Antarmuka Collection dan Kelas AbstractCollection
Antarmuka Collection merupakan antarmuka akar untuk memanipulasi sekumpulan
objek. Beberapa metode publik ditampilkan pada Gambar 8.2. Kelas AbstractCollection merupakan suatu
kelas yang menyediakan implementasi parsial untuk antarmuka Collection. Kelas tersebut
mengimplementasikan semua metode di dalam Collection
kecuali metode size dan iterator.
Antarmuka Collection menyediakan operasi-operasi dasar untuk menambah dan
menghapus elemen di dalam suatu koleksi. Metode add menambah suatu elemen pada koleksi. Metode addAll menambah semua elemen di dalam koleksi tertentu pada koleksi
lain. Metode remove menghapus atau
membuang suatu elemen dari koleksi. Metode removeAll
menghapus semua elemen dari koleksi yang ada pada koleksi tertentu. Metode retainAll mendapatkan elemen-elemen
dalam koleksi yang ada pada koleksi tertentu. Semu metode ini mengembalikan boolean. Nilai balik true jika koleksi diubah sebagai akibat
dari eksekusi metode. Metode clear()
menghapus semua elemen dari koleksi.
Gambar 8.2 Antarmuka Collection memuat metode-metode untuk memanipulasi elemen-elemen di
dalam suatu koleksi, dan Anda bisa mendapatkan suatu objek iterator untuk menjelajah
elemen-elemen di dalam koleksi
Antarmuka Collection menyediakan berbagai operasi query. Metode size mengembalikan jumlah elemen di
dalam koleksi. Metode contains
memeriksa apakah koleksi mempunyai elemen tertentu. Metode containsAll memeriksa apakah koleksi mempunyai semua elemen di
dalam koleksi tertentu. Metode isEmpty
mengembalikan true jika koleksi kosong.
Antarmuka Collection menyediakan metode toArray()
yang mengembalikan suatu representasi array untuk koleksi.
Koleksi bisa berupa set atau list. Antarmuka Iterator menyediakan suatu cara seragam
untuk menjelajah elemen-elemen dalam berbagai jenis koleksi. Metode iterator
dalam antarmuka Collection
mengembalikan suatu instans dari antarmuka Iterator,
seperti tertampil pada Gambar 8.2, yang menyediakan akses sekuensial terhadap
elemen-elemen dalam koleksi menggunakan metode next(). Anda juga bisa menggunakan metode hasNext() untuk memeriksa apakah masih terdapat elemen di dalam
iterator, dan metode remove() untuk
menghapus elemen terakhir yang dikembalikan oleh iterator.
8.4
Set
Antarmuka Set mewarisi antarmuka Collection.
Antarmuka ini tidak memiliki metode atau konstanta baru, tetapi menjamin bahwa
suatu instans Set tidak memiliki
elemen-elemen duplikat. Kelas konkrit yang mengimplementasikan Set harus memastikan bahwa tidak
terdapat elemen duplikat yang dapat ditambahkan ke dalam set. Yaitu, tidak
terdapat dua elemen e1 dan e2 yang berada di dalam set yang
membuat e1.equals(e2) bernilai true.
Gambar 8.3 JCF menyediakan tiga kelas set konkrit
Kelas AbstractSet
merupakan kelas yang mewarisi AbstractCollection
dan yang mengimplementasikan Set.
Kelas AbstractSet menyediakan
implementasi konkrit untuk metode equals
dan metode hashCode. Kode hash atas
suatu set adalah penjumlahan atas kode hash dari semua elemen di dalam set.
Karena metode size dan metode iterator tidak diimplementasikan di
dalam kelas AbstractSet, maka AbstractSet merupakan suatu kelas
abstrak.
Tiga kelas konkrit dari Set adalah HashSet, LinkedSet, dan TreeSet, seperti ditampilkan pada Gambar 8.3.
8.4.1
HashSet
Kelas HashSet merupakan suatu kelas konkrit
yang mengimplementasikan Set. Anda
bisa menciptakan suatu hash kosong menggunakan konstruktor tanpa-argumen atau
menciptkan suatu set hash dari koleksi yang ada. Secara default, kapasitas awal
adalah 16 dan faktor beban adalah 0.75. Jika Anda mengetahui ukuran set Anda,
maka Anda bisa menspesifikasi kapasitas awal dan faktor beban di dalam
konstruktor. Sebaliknya bila Anda tidak mengetahuinya, sebaiknya digunakan
spesifikasi default. Faktor beban merupakan suatu nilai antara 0.0 sampai 1.0.
Faktor
beban merupakan takaran untuk mengukur seberapa penuh suatu set diijinkan
sebelum kapasitasnya ditambah. Ketika jumlah elemen melebihi perkalian antara
kapasitas dengan faktor beban, kapasitas secara otomatis akan digandakan. Sebagai
contoh, jika kapasitas adalah 16 dan faktor beban adalah 0.75, maka kapasitas
akan digandakan menjadi 32 bila ukuran set meraih 12 (16 * 0.75 = 12). Faktor
beban yang lebih tinggi akan mengurangi biaya memori namun meningkatkan waktu
pencarian. Secara umum, faktor beban default 0.75 merupakan pilihan terbaik
mengingat pertimbangan biaya memori dan waktu pencarian.
HashSet dapat
digunakan untuk menyimpan elemen-elemen bebas-duplikat. Demi efisiensi,
objek-objek yang ditambahkan ke dalam set hash perlu mengimplementasikan metode
hashCode. Ingat bahwa hashCode didefinisikan di dalam kelas Object. Kode hash atas dua objek harus
sama bila kedua objek adalah sama. Dua objek yang tidak sama bisa jadi memiliki
kode hash yang sama, tetapi Anda harus mengimplementasikan metode hashCode untuk menghindari terlalu
banyak kasus seperti itu. Kebanyakan kelas dalam JAVA API mengimplementasikan hashCode. Sebagai contoh, hashCode di dalam kelas Integer mengembalikan nilai balik int. hashCode di dalam kelas Character
mengembalikan kode Unicode atas suatu karakter. hashCode di dalam kelas String
mengembalikan
, dimana
adalah s.charAt(i).
Kode8.1
menyajikan suatu program yang menciptakan suatu set hash untuk menyimpan
string-string dan menggunakan suatu iterator untuk menjelajah elemen-elemen di
dalam set tersebut.
Kode8.1 UjiSetHash.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
import java.util.*;
public class UjiSetHash {
public static void main(String[]
args) {
// Menciptakan suatu set hash
Set<String> set = new HashSet<String>();
// Menambahkan string-string ke dalam set
set.add("Klaten");
set.add("Balige");
set.add("Jogjakarta");
set.add("Mataram");
set.add("Siantar");
set.add("Jogjakarta ");
System.out.println(set);
// Mendapatkan suatu iterator untuk set
hash
Iterator<String> iterator = set.iterator();
// Menampilkan elemen-elemen di dalam set
hash
while(iterator.hasNext()) {
System.out.print(iterator.next().toUpperCase() + "
");
}
}
}
|
Keluaran
[Klaten, Jogjakarta,
Mataram, Siantar, Balige]
KLATEN JOGJAKARTA MATARAM
SIANTAR BALIGE
String-string
ditambahkan ke dalam set (baris 9-14). “Jogjakarta”ditambahkan
dua kali ke dalam set, namun hanya satu yang disimpan, karena set tidak
mengijinkan duplikasi elemen.
Seperti
yang tertampil di dalam keluaran, string-string tidak disimpan terurut sesuai
saat disisipkan ke dalam set. Tidak ada urutan khusus di dalam set hash. Untuk
menerapkan suatu urutan, Anda perlu menggunakan kelas LinkedHashSet, yang akan dikenalkan pada bagian selanjutnya.
Karena
set merupakan suatu instans dari Collection,
semua metode yang didefinisikan dalam Collection
dapat digunakan untuk set. Kode8.2 menyajikan suatu contoh yang mengeksplorasi
metode-metode di dalam antarmuka Collection.
Kode8.2 UjiMetodeDlmKoleksi.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
public class UjiMetodeDlmKoleksi {
public static void main(String[]
args) {
// Menciptakan set1
java.util.Set<String> set1 = new
java.util.HashSet<String>();
// Menambahkan string ke dalam set1
set1.add("Batam");
set1.add("Siantar");
set1.add("Tebing Tinggi");
set1.add("Bandung");
set1.add("Bekasi");
System.out.println("set1 adalah
" + set1);
System.out.println(set1.size() + " elemen di dalam set1");
// Menghapus suatu string dari set1
set1.remove("Batam");
System.out.println("\nset1 adalah
" + set1);
System.out.println(set1.size() + " elemen
di dalam set1");
// Menciptakan set2
java.util.Set<String> set2 = new
java.util.HashSet<String>();
// Menambahkan string ke dalam set2
set2.add("Batam");
set2.add("Mataram");
set2.add("Bekasi");
System.out.println("\nset2 adalah
" + set2);
System.out.println(set2.size() + " elemen di dalam set2");
System.out.println("\nApakah
Klaten di dalam set2? "
+ set2.contains("Klaten"));
set1.addAll(set2);
System.out.println("\nSetelah
menambah set2 ke dalam set1, set1 adalah "
+ set1);
set1.removeAll(set2);
System.out.println("Setelah
menghilangkan set2 dari set1, set1 adalah "
+ set1);
set1.retainAll(set2);
System.out.println("Setelah
menghilangkan elemen sama di dalam set2 "
+ "dari set1, set1 adalah
" + set1);
}
}
|
Keluaran
set1 adalah [Bandung,
Tebing Tinggi, Bekasi, Batam, Siantar]
5 elemen di dalam set1
set1 adalah [Bandung,
Tebing Tinggi, Bekasi, Siantar]
4 elemen di dalam set1
set2 adalah [Bekasi, Batam,
Mataram]
3 elemen di dalam set2
Apakah Klaten di dalam
set2? false
Setelah menambah set2 ke
dalam set1, set1 adalah
[Bandung, Tebing Tinggi, Batam, Bekasi,
Mataram, Siantar]
Setelah menghilangkan set2
dari set1, set1 adalah
[Bandung, Tebing Tinggi, Siantar]
Setelah menghilangkan
elemen-elemen sama di dalam set2 dari set1, set1 adalah []
Program
menciptakan dua set (baris 4, 22). Metode size()
mengembalikan jumlah elemen di dalam suatu set (baris 14). Baris 17
set1.add("Batam");
menghilangkan
“Batam” dari set1. Metode contains
(baris 32) memeriksa apakah suatu elemen berada di dalam set atau tidak. Baris
34
set1.addAll(set2);
menambahkan set2 ke dalam set1.
Jadi, set1 menjadi [Bandung, Tebing Tinggi, Batam, Bekasi,
Mataram, Siantar].
Baris 38
set1.removeAll(set2);
menghapus
set2 dari set1. Jadi set1 menjadi [Bandung, Tebing Tinggi, Siantar].
Baris 42
set1.retainAll(set2);
menempatkan
elemen-elemen sama ke dalam set1.
Karena set1 dan set2 tidak memiliki elemen yang sama, set1 menjadi kosong.
8.4.2
LinkedHashSet
LinkedHashSet mewarisi
HashSet dengan implementasi
list-berantai atau senarai-berantai yang mendukung pengurutan elemen di dalam
set. Elemen-elemen di dalam HashSet
tidak terurut, tetapi elemen-elemen di dalam LinkedHashSet dapat dibuat berurutan seperti saat disisipkan ke
dalam set. LinkedHashSet dapat
diciptakan menggunakan salah satu dari empat konstruktornya, seperti
ditampilkan pada Gambar 8.3. Keempat konstruktor tersebut sama dengan
konstruktor pada HashSet.
Kode8.3
menyajikan suatu program uji untuk LinkedHashSet.
Program cuma mengganti HashSet pada
kode8.1 dengan LinkedHashSet.
Kode8.3 UjiLinkedHashSet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
import java.util.*;
public class UjiLinkedHashSet {
public static void main(String[]
args) {
// Menciptakan suatu set hash
Set<String> set = new LinkedHashSet<String>();
// Menambahkan string-string ke dalam set
set.add("Klaten");
set.add("Balige");
set.add("Jogjakarta");
set.add("Mataram");
set.add("Siantar");
set.add("Jogjakarta ");
System.out.println(set);
// Mendapatkan suatu iterator untuk set
hash
Iterator<String> iterator = set.iterator();
// Menampilkan elemen-elemen di dalam set
hash
while(iterator.hasNext()) {
System.out.print(iterator.next().toUpperCase() + "
");
}
}
}
|
Keluaran
[Klaten, Balige,
Jogjakarta, Mataram, Siantar]
KLATEN BALIGE JOGJAKARTA
MATARAM SIANTAR
Suatu LinkedHashSet diciptakan pada baris 6.
Seperti tertampil pada keluaran, string disimpan berurutan sama seperti ketika
dimasukkan ke dalam set. Karena LinkedHashSet
merupakan suatu set, LinkedHashSet tidak bisa menyimpan elemen-elemen duplikat.
LinkedHashSet
mempertahankan urutan ketika dimasukkan ke dalam set. Untuk memaksakan urutan
lain (misalnya, urutan menaik atau menurun), Anda bisa menggunakan kelas TreeSet yang akan dikenalkan pada
bagian selanjutnya.
8.4.3
TreeSet
SortedSet
merupakan suatu subantarmuka dari Set,
yang menjamin bahwa elemen-elemen di dalam set diurutkan. Lebih lagi,
subantarmuka SortedSet menyediakan
metode first() dan last() untuk mengembalikan elemen
pertama dan elemen terakhir di dalam suatu set, dan metode headSet(toElement) dan tailSet(fromElement)
untuk mengembalikan sebagian dari set yang memiliki elemen-elemen kurang dari toElement dan lebih dari atau sama
dengan fromElement.
NavigableSet mewarisi
SortedSet untuk menyediakan
metode-metode navigasi lower(e), floor(e), ceiling(e), dan higher(e)
yang mengembalikan elemen-elemen kurang dari, kurang dari atau sama dengan,
lebih dari atau sama dengan, dan lebih dari suatu elemen yang diberikan dan
mengembalikan null jika tidak
ditemukan elemen-elemen seperti itu. Metode pollFirst() dan pollLast()
menghapus dan mengembalikan elemen pertama dan elemen terakhir di dalam TreeSet.
TreeSet
mengimplementasikan antarmuka SortedSet.
Untuk menciptakan suatu TreeSet,
digunakan konstruktor, seperti tertampil pada Gambar 8.3. Anda bisa menambahkan
objek-objek ke dalam set tree sepanjang objek-objek tersebut bisa dibandingkan
satu sama lain. Ada dua cara membandingkan objek:
·
Menggunakan antarmuka Comparable.
Karena objek-objek yang ditambahkan ke dalam set merupakan instans dari Comparable, objek-objek tersebut bisa
dibandingkan menggunakan metode compareTo.
Beberapa kelas dalam JAVA API, seperti String,
Date, Calendar, dan semua kelas wrapper untuk tipe primitif,
mengimplementasikan antarmuka Comparable.
Pendekatan ini dinamai urutan alamiah.
·
Jika kelas tidak mengimplementasikan antarmuka Comparable, atau jika Anda tidak ingin menggunakan metode compareTo di dalam kelas yang
mengimplementasikan antarmuka Comparable,
maka spesifikasi suatu komparator untuk elemen-elemen di dalam set. Pendekatan
ini dinamai dengan urutan dengan komparator.
Kode8.4
menyajikan suatu contoh untuk mengurutkan elemen-elemen menggunakan antarmuka Comparable. Contoh terdahulu pada
kode8.3 menampilkan semua string dalam urutan yang sama ketika dimasukkan.
Contoh ini menulis-ulang contoh terdahulu untuk menampilkan string-string dalam
urutan alfabetikal menggunakan kelas TreeSet.
Kode8.4 UjiTreeSet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import java.util.*;
public class UjiTreeSet {
public static void main(String[]
args) {
// Menciptakan suatu set hash
Set<String> set = new HashSet<String>();
// Menambah string ke dalam set
set.add("Klaten");
set.add("Balige");
set.add("Jogjakarta");
set.add("Mataram");
set.add("Siantar");
set.add("Jogjakarta");
TreeSet<String> treeSet = new
TreeSet<String>(set);
System.out.println("Set tree
terurut: " + treeSet);
// Menggunakan metode-metode dalam
antarmuka SortedSet
System.out.println("first():
" + treeSet.first());
System.out.println("last():
" + treeSet.last());
System.out.println("headSet():
" + treeSet.headSet("Jogjakarta"));
System.out.println("tailSet():
" + treeSet.tailSet("Jogjakarta"));
// Menggunakan metode-metode dalam
antarmuka NavigableSet
System.out.println("lower(\"P\"):
" + treeSet.lower("P"));
System.out.println("higher(\"P\"):
" + treeSet.higher("P"));
System.out.println("floor(\"P\"):
" + treeSet.floor("P"));
System.out.println("ceiling(\"P\"):
" + treeSet.ceiling("P"));
System.out.println("pollFirst():
" + treeSet.pollFirst());
System.out.println("pollLast():
" + treeSet.pollLast());
System.out.println("New tree set:
" + treeSet);
}
}
|
Keluaran
Set tree terurut: [Balige,
Jogjakarta, Klaten, Mataram, Siantar]
first(): Balige
last(): Siantar
headSet(): [Balige]
tailSet(): [Jogjakarta,
Klaten, Mataram, Siantar]
lower("P"):
Mataram
higher("P"):
Siantar
floor("P"):
Mataram
ceiling("P"):
Siantar
pollFirst(): Balige
pollLast(): Siantar
New tree set: [Jogjakarta,
Klaten, Mataram]
Contoh
ini menciptakan suatu set hash yang diisi dengan string, kemudian menciptakan
suatu set tree yang diisi dengan string yang sama. String-string tersebut
diurutkan di dalam set tree menggunakan metode compareTo di dalam antarmuka Comparable.
Elemen-elemen
di dalam set diurutkan begitu Anda menciptakan objek TreeSet dari suatu objek HashSet
menggunakan new TreeSet(hashSet)
(baris 16). Anda bisa menulis-ulang program untuk menciptakan suatu instans TreeSet menggunakan konstruktor
tanpa-argumennya, dan menambahkan string-string ke dalam objek TreeSet. Kemudian, setiap kali string
ditambahkan ke dalam objek TreeSet,
elemen-elemen di dalamnya akan diurutkan-ulang. Pendekatan yang digunakan dalam
contoh ini secara umum lebih efisien karena hanya memerlukan pengurutan
satu-kali.
Metode treeSet.first() mengembalikan elemen
pertama di dalam treeSet (baris 20).
Metode treeSet.last() mengembalikan
elemen terakhir di dalam treeSet
(baris 21). Metode treeSet.headSet(“Jogjakarta”)
mengembalikan elemen-elemen di dalam treeSet
sebelum Jogjakarta (baris 22). Metode treeSet.tailSet(“Jogjakarta”)
mengembalikan elemen-elemen di dalam treeSet
setelah Jogjakarta, termasuk Jogjakarta (baris 23).
Metode treeSet.lower(“P”) mengembalikan elemen
terbesar yang kurang dari “P” di
dalam treeSet (baris 26). Metode treeSet.higher(“P”) mengembalikan
elemen terkecil yang lebih dari “P”
di dalam treeSet (baris 27). Metode treeSet.floor(“P”) mengembalikan elemen
terbesar yang kurang dari atau sama dengan “P” di dalam treeSet
(baris 28). Metode treeSet.ceiling(“P”)
mengembalikan elemen terkecil yang lebih dari atau sama dengan “P” di dalam treeSet (baris 29). Metode treeSet.pollFirst()
menghapus elemen pertama di dalam treeSet
dan mengembalikan elemen yang dihapus (baris 30). Metode treeSet.pollLast() menghapus elemen terakhir di dalam treeSet dan mengembalikan elemen yang
dihapus (baris 31).
8.5
Antarmuka Comparator
Kadangkala
Anda ingin menyisipkan elemen-elemen ke dalam suatu set tree. Elemen-elemen
tersebut bisa jadi bukan instans dari java.lang.Comparable.
Anda dapat mendefinisikan suatu komparator untuk membandingkan elemen-elemen
ini. Untuk melakukannya, perlu diciptakan suatu kelas yang mengimplementasikan
antarmuka java.util.Comparator.
Antarmuka Comparator memiliki dua
metode, compare dan equals.
·
public int compare(Object elemen1, Object
elemen2)
Mengembalikan suatu nilai negatif jika elemen1 lebih kecil dari elemen2, suatu nilai positif jika elemen1 lebih besar dari elemen2, dan nilai nol jika elemen1 sama dengan elemen2.
·
public boolean equals(Object elemen)
Mengembalikan true
jika objek yang dispesifikasi juga merupakan suatu komparator dan menerapkan
pengurutan yang sama seperti komparator ini.
Metode equals juga didefinisikan di dalam
kelas Object. Oleh karena itu, Anda
tidak akan mendapatkan error kompilasi bahkan bila Anda tidak
mengimplementasikan metode equals di
dalam kelas komparator Anda. Namun, dalam beberapa kasus, pengimplementasian metode
ini dapat memperbaiki kinerja dengan mengijinkan program untuk menentukan
secara cepat apakah dua komparator yang berbeda dapat menerapkan pengurutan
yang sama.
Kode8.5
mendefinisikan suatu Comparator
untuk objek-objek geometri. ObjekGeometri
didefinisikan dalam Bab 1. Baris 4 mengimplementasikan Comparator<ObjekGeometri>. Baris 5 mengoverride metode compare untuk membandingkan dua objek
geometri. Kelas komparator tersebut juga mengimplementasikan Serializable. Agar struktur data dapat
berhasil diserialkan, komparator harus mengimplementasikan Serializable.
Kode8.5 KomparatorObjekGeometri.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.util.Comparator;
public class KomparatorObjekGeometri
implements Comparator<ObjekGeometri>, java.io.Serializable
{
public int compare(ObjekGeometri o1, ObjekGeometri o2){
double luas1 = o1.dapatLuas();
double luas2 = o2.dapatLuas();
if (luas1 < luas2)
return -1;
else if (luas1 == luas2)
return 0;
else
return 1;
}
}
|
Jika Anda
menciptakan suatu TreeSet
menggunakan konstruktor tanpa-argumennya, maka metode compareTo digunakan untuk membandingkan elemen-elemen di dalam set,
dengan asumsi bahwa kelas dari elemen-elemen tersebut mengimplementasikan Comparable. Untuk menggunakan suatu
komparator, Anda harus menggunakan konstruktor TreeSet(Comparator komparator) untuk menciptakan suatu set terurut
yang menggunakan metode compare di
dalam komparator untuk mengurutkan elemen-elemen di dalam set.
Kode8.6
menyajikan suatu program yang mendemonstrasikan bagaimana mengurutkan
elemen-elemen di dalam set tree menggunakan antarmuka Comparator. Contoh ini menciptakan suatu set tree yang memuat
objek-objek geometri pada baris 6-11. Objek-objek geometri tersebut diurutkan
menggunakan metode compare di dalam
antarmuka Comparator.
Kode8.6 UjiTreeSetDenganKomparator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import java.util.*;
public class UjiTreeSetDenganKomparator {
public static void main(String[]
args) {
// Menciptakan set tree untuk objek-objek geometri menggunakan
komparator
Set<ObjekGeometri> set =
new TreeSet<ObjekGeometri>(new KomparatorObjekGeometri());
set.add(new PersegiPanjang(4, 5));
set.add(new Lingkaran(40));
set.add(new Lingkaran(40));
set.add(new PersegiPanjang(4, 1));
// Menampilkan objek-objek geometri di
dalam set tree
System.out.println("Suatu set
terurut yang memuat objek-objek geometri");
for (ObjekGeometri elemen: set)
System.out.println("luas =
" + elemen.dapatLuas());
}
}
|
Keluaran
Suatu set terurut yang
memuat objek-objek geometri
luas = 4.0
luas = 20.0
luas = 5026.548245743669
Kelas Lingkaran dan PersegiPanjang didefinisikan pada Bab1.2, keduanya merupakan
subkelas dari ObjekGeometri.
8.6
List
Suatu set
menyimpan elemen-elemen nonduplikat. Untuk mengijinkan elemen-elemen duplikat
disimpan di dalam suatu koleksi, Anda membutuhkan suatu list. Suatu list tidak
hanya dapat menyimpan elemen-elemen duplikat tetapi juga mengijinkan pengguna
untuk menentukan dimana elemen-elemen disimpan. Pengguna dapat mengakses elemen
melalui suatu indeks. Antarmuka List
mewarisi Collection untuk
mendefinisikan suatu koleksi terurut dengan elemen-elemen duplikat diijinkan
untuk disimpan di dalamnya. Antarmuka List menambahkan operasi-operasi
berorientasi-posisi, begitu pula suatu iterator list yang baru yang memampukan
pengguna untuk menjelajah list secara dua-arah. Metode-metode baru di dalam
antarmuka List ditampilkan pada
Gambar 8.4.
Gambar
8.4 Antarmuka List menyimpan elemen-elemen secara berurutan dan mengijinkan
duplikasi
Metode add(index, element) digunakan untuk
menyisipkan suatu elemen pada indeks tertentu,dan metode addAll(index, collection) untuk menyisipkan suatu koleksi pada
indeks tertentu. Metode remove(index)
digunakan untuk menghapus suatu elemen pada indeks tertentu dari list. Suatu
elemen baru dapat ditetapkan pada indeks tertentu menggunakan metode set(index, element).
Metode indexOf(element) digunakan untuk
memperoleh indeks dari kemunculan pertama atas elemen tertentu di dalam list,
dan Metode lastIndexOf(element)
digunakan untuk memperoleh indeks dari kemunculan terakhir atas elemen tertentu
di dalam list. Suatu sublist didapatkan menggunakan metode subList(fromIndex, toIndex).
Metode listIterator() atau listIterator(startIndex) mengembalikan
suatu instans dari ListIterator.
Antarmuka ListIterator mewarisi
antarmuka Iterator untuk menambah
kemampuan penyebaran dua-arah pada list. Metode-metode di dalam ListIterator ditampilkan pada Gambar
8.5.
Gambar
8.5 ListIterator memampukan Anda untuk menjelajah elemen secara
dua-arah (bidireksional)
Metode add(element) menyisipkan elemen
tertentu ke dalam list. Elemen tersebut disisipkan tepat sebelum elemen
berikutnya yang dikembalikan oleh metode next()
yang didefinisikan di dalam antarmuka Iterator,
jika ada, dan setelah elemen yang dikembalikan oleh metode previous(). Jika list tidak memiliki elemen, elemen baru menjadi
satu-satunya elemen dalam list. Metode set(element)
dapat digunakan untuk mengganti elemen terakhir yang dikembalikan oleh metode next() atau oleh metode previous() dengan elemen tertentu.
Metode hasNext() yang didefinisikan di dalam
antarmuka Iterator digunakan untuk memeriksa apakah iterator memiliki
elemen-elemen lagi yang akan disebarkan pada arah maju, dan metode hasPrevious() yang didefinisikan di
dalam antarmuka Iterator digunakan
untuk memeriksa apakah iterator memiliki elemen-elemen lagi yang akan
disebarkan pada arah mundur.
Metode next() yang didefinisikan di dalam
antarmuka Iterator mengembalikan
elemen berikutnya di dalam iterator, dan metode previous() yang didefinisikan di dalam antarmuka Iterator mengembalikan elemen
sebelumnya di dalam iterator. Metode nextIndex()
mengembalikan indeks dari elemen berikutnya di dalam iterator dan metode previousIndex() mengembalikan indeks
dari elemen berikutnya di dalam iterator.
Kelas AbstractList menyediakan implementasi
parsial untuk antarmuka List. Kelas AbstractSequentialList mewarisi AbstractList untuk menyediakan dukungan
bagi list berantai.
8.6.1
Kelas ArrayList dan LinkedList
Kelas ArrayList dan kelas LinkedList merupakan dua implementasi
konkrit dari antarmuka List. ArrayList menyimpan elemen-elemen di
dalam suatu array. Array tersebut diciptakan secara dinamis. Jika kapasitas
array dilampaui, maka suatu array yang lebih besar diciptakan dan semua elemen
dari array sekarang disalin kepada array yang baru tersebut. LinkedList menyimpan elemen-elemen di
dalam suatu senarai atau daftar atau list berantai. Mana dari dua kelas ini
yang akan Anda pakai tergantung dari kebutuhan spesifik Anda. Jika Anda perlu
untuk mendukung akses acak melalui suatu indeks tanpa penyisipan atau
penghapusan elemen-elemen kecuali pada ujung list, ArrayList menawarkan koleksi yang paling efisien. Namun jika
aplikasi Anda memerlukan penyisipan atau penghapusan elemen-elemen di mana saja
di dalam list, maka Anda harus memilih LinkedList.
Suatu list bisa bertambah atau berkurang secara dinamis. Begitu diciptakan, array
berukuran tetap. Jika aplikasi Anda tidak memerlukan penyisipan atau
penghapusan elemen-elemen, maka array merupakan struktur data paling efisien untuk tujuan
tersebut.
ArrayList
merupakan implementasi array atas antarmuka List, dengan kapasitas yang bisa diperbesar atau diperkecil. Kelas
ini juga menyediakan beberapa metode untuk memanipulasi ukuran array yang
digunakan secara internal untuk menyimpan list, seperti tertampil pada Gambar
8.6. Setiap instans dari ArrayList
memiliki suatu kapasitas, yang berupa ukuran array yang digunakan untuk
menyimpan elemen-elemen di dalam list. Begitu elemen-elemen ditambahkan pada
suatu ArrayList, kapasitasnya
bertambah secara otomatis. Suatu ArrayList
tidak secara otomatis menyusut. Anda bisa menggunakan metode trimToSize() untuk mereduksi kapasitas
array menjadi seukuran dengan list. Suatu ArrayList
dapat diciptakan menggunakan konstruktor tanpa-argumennya, ArrayList-(Collection), atau ArrayList(initialCapacity).
Gambar
8.6 ArrayList mengimplementasikan List
menggunakan array
LinkedList
merupakan implementasi list berantai dari antarmuka List. Kelas ini menyediakan beberapa metode untuk menarik,
menyisipkan, dan menghapus elemen-elemen dari kedua ujung list, seperti
tertampil pada Gambar 8.7. Suatu LinkedList
dapat diciptakan menggunakan konstruktor tanpa-argumennya atau LinkedList(Collection).
Gambar
8.7 LinkedList menyediakan beberapa metode untuk menambahkan dan
menyisipkan elemen-elemen pada kedua ujung list
Kode8.7
menyajikan suatu program yang menciptakan suatu array yang diisi dengan
angka-angka dan menyisipkan elemen-elemen baru pada lokasi-lokasi tertentu di
dalam list. Contoh ini juga menciptakan suatu list berantai dari list array
tersebut dan menyisipkan dan menghapus elemen-elemen dari list. Terakhir,
contoh ini juga menjelajah list secara maju maupun mundur.
Kode8.7 UjiArrayDanLinkedList.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
import java.util.*;
public class UjiArrayDanLinkedList {
public static void main(String[]
args) {
List<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1); // 1 diautobox menjadi
new Integer(1)
arrayList.add(2);
arrayList.add(3);
arrayList.add(1);
arrayList.add(4);
arrayList.add(0, 10);
arrayList.add(3, 30);
System.out.println("Suatu list
integer di dalam list array:");
System.out.println(arrayList);
LinkedList<Object> linkedList = new LinkedList<Object>(arrayList);
linkedList.add(1, "merah");
linkedList.removeLast();
linkedList.addFirst("hijau");
System.out.println("Menampilkan
list berantai secara maju:");
ListIterator<Object> listIterator = linkedList.listIterator();
while (listIterator.hasNext()) {
System.out.print(listIterator.next() +
" ");
}
System.out.println();
System.out.println("Menampilkan
list berantai secara mundur:");
listIterator = linkedList.listIterator(linkedList.size());
while (listIterator.hasPrevious())
{
System.out.print(listIterator.previous()
+ " ");
}
}
}
|
Keluaran
Suatu list integer di dalam
list array:
[10, 1, 2, 30, 3, 1, 4]
Menampilkan list berantai
secara maju:
hijau 10 merah 1 2 30 3 1
Menampilkan list berantai
secara mundur:
1 3 30 2 1 merah 10 hijau
Suatu
list dapat memuat elemen-elemen yang identik. Integer 1 disimpan dua kali di
dalam list (baris 6, 9). ArrayList
dan LinkedList dioperasikan dengan
cara sama. Perbedaan penting dari keduanya ada pada implementasi internal, yang
mempengaruhi kinerjanya. ArrayList
sangat efisien untuk menarik atau mendapatkan elemen-elemen dan untuk
menyisipkan dan menghapus elemen-elemen pada kedua ujung list. LinkedList sangat efisien untuk
menyisipkan dan menghapus elemen-elemen di mana saja di dalam list.
8.6.2
Metode Statik Untuk List Dan Koleksi
Anda bisa
menggunakan TreeSet untuk menyimpan
elemen-elemen terurut di dalam suatu set. Tetapi dalam list, tidak ada
pengurutan. Akan tetapi, JCF menyediakan beberapa metode statik di dalam kelas Collection yang bisa dipakai untuk
mengurutkan suatu list. Kelas Collection
juga memuat metode binarySearch, reverse, shuffle, copy, dan fill untuk
memanipulasi list, dan metode max, min, disjoint, dan frequency
untuk memanipulasi koleksi, seperti tertampil pada Gambar 8.8.
Anda bisa
mengurutkan elemen-elemen komparabel di dalam list dengan urutan alamiah
melalui metode compareTo di dalam
antarmuka Comparable. Anda juga bisa
menspesifikasi suatu komparator untuk mengurutkan elemen. Sebagai contoh, kode
berikut mngurutkan string di dalam suatu list:
List<String> list =
Arrays.asList("merah",
"hijau", "biru");
Collections.sort(list);
System.out.println(list);
Keluarannya
adalah [biru, hijau, merah].
Kode
terdahulu mengurutkan suatu list dengan urutan menaik. Untuk mengurutkannya
secara menurun, Anda bisa menggunakan metode Collections.reverseOrder() untuk mengembalikan suatu objek Comparator yang mengurutkan elemen
secara menurun. Sebagai contoh, kode berikut mengurutkan string di dalam list
dengan urutan menurun:
List<String> list =
Arrays.asList("kuning",
"merah", "hijau",
"biru");
Collections.sort(list,
Collections.reverseOrder());
System.out.println(list);
Keluarannya
adalah [merah, kuning, hijau, biru].
Gambar
8.8 Kelas Collections memuat beberapa metode statik untuk memanipulasi
koleksi dan list
Anda bisa
menggunakan metode binarySearch
untuk mencari kunci di dalam list. List terlebih dahulu diurutkan secara
menaik. Jika kunci tidak berada dalam list, maka metode mengembalikan -( titik penyisipan + 1). Ingat bahwa titik
penyisipan adalah dimana item akan ditempatkan bila item tersebut berada di
dalam list. Sebagai contoh, kode berikut mencari beberapa kunci di dalam list
integer dan list string.
List<Integer> list1 =
Arrays.asList(2,
4, 7,
10, 11,
45, 50,
59, 60,
66);
System.out.println("(1)
Indeks: " + Collections.binarySearch(list1, 7));
System.out.println("(2)
Indeks: " + Collections.binarySearch(list1, 9));
List<String> list2 =
Arrays.asList("biru",
"hijau", "merah");
System.out.println("(3)
Indeks: " +
Collections.binarySearch(list2, "merah"));
System.out.println("(4)
Indeks: " +
Collections.binarySearch(list2,
"cyan"));
Keluarannya
adalah
(1) Indeks: 2
(2) Indeks: -4
(3) Indeks: 2
(4) Indeks: -2
Anda bisa
menggunakan metode reverse untuk
membalikkan elemen-elemen di dalam list. Sebagai contoh, kode berikut
menampilkan [biru, hijau, merah, kuning].
List<String> list =
Arrays.asList("kuning",
"merah", "hijau",
"biru");
System.out.println(list);
Collections.reverse(list);
Anda bisa
memakai metode shuffle(List) untuk
menata secara acak elemen-elemen di dalam suatu list. Sebagai contoh, kode
berikut mengacak elemen-elemen di dalam list.
List<String> list =
Arrays.asList("kuning",
"merah", "hijau",
"biru");
Collections.shuffle(list);
System.out.println(list);
Anda juga
bisa memakai metode shuffle(List,
Random) untuk mengacak elemen-elemen di dalam suatu list dengan objek Random tertentu. Pemakaian suatu objek Random tertentu berguna dalam
membangkitkan suatu list dengan runtun elemen identik untuk list awal yang
sama. Sebagai contoh, kode berikut mengacak elemen-elemen di dalam list.
List<String>
list1 = Arrays.asList("kuning", "merah", "hijau", "biru");
List<String>
list2 = Arrays.asList("kuning", "merah", "hijau", "biru");
Collections.shuffle(list1,
new Random(20));
Collections.shuffle(list2,
new Random(20));
System.out.println(list1);
System.out.println(list2);
Anda akan
melihat bahwa list1 dan list2 memiliki runtun elemen yang sama
sebelum dan sesudah pengacakan.
Anda
sapat memakai metode copy(det, src)
untuk menyalin semua elemen dari list sumber ke list tujuan dengan indeks yang
sama. List tujuan harus sama panjang dengan list sumber. Jika list tujuan lebih
panjang dari list sumber, maka elemen-elemen sisa di dalam list tujuan tidak
akan terpengaruhi. Sebagai contoh, kode berikut menyalin dari list1 ke list2.
List<String> list1 =
Arrays.asList("kuning", "merah", "hijau", "biru");
List<String> list2 =
Arrays.asList("putih",
"hitam");
Collections.copy(list1, list2);
System.out.println(list1);
Keluaran
untuk list1 adalah [putih, hitam,hijau, biru]. Metode copy
melakukan penyalinan dangkal. Hanya referensi dari elemen-elemen list sumber
yang disalin.
Anda bisa
memakai metode nCopies(int n, Object o)
untuk menciptakan suatu list immutabel yang memiliki n salinan dari objek tertentu. Sebagai contoh, kode berikut
menciptakan suatu list dengan lima objek Calendar.
List<GregorianCalendar> list1 = Collections.nCopies
(5, new GregorianCalendar(2005, 0, 1));
List yang
diciptakan dari metode nCopies
bersifat immutabel, jadi Anda tidak bisa menambah, menghapus, atau memperbarui
elemen di dalam list. Semua elemen memiliki referensi sama.
Anda bisa
menggunakan metode fill(List list,
Object o) untuk mengganti semua elemen di dalam list dengan elemen
tertentu. Sebagai contoh, kode berikut menampilkan [hitam, hitam, hitam].
List<String>
list = Arrays.asList("merah", "hijau", "biru");
Collections.fill(list,
"hitam");
System.out.println(list);
Anda bisa
menggunakan metode max dan min untuk menemukan elemen maksimum dan
minimum di dalam suatu koleksi. Elemen-elemen harus komparabel menggunakan
antarmuka Comparable atau antarmuka Comparator. Sebagai contoh, kode
berikut menampilkan string terbesar dan string terkecil di dalam suatu koleksi.
Collection<String> collection
= Arrays.asList("merah",
"hijau", "biru");
System.out.println(Collections.max(collection));
System.out.println(Collections.min(collection));
Metode disjoint(collection1, collection2)
mengembalikan true bila dua koleksi
tidak memiliki elemen yang sama. Sebagai contoh, di dalam kode berikut, disjoint(collection1, collection2)
mengembalikan false, tetapi disjoint-(collection1, collection3)
mengembalikan true.
Collection<String> collection1
= Arrays.asList("merah",
"hitam");
Collection<String> collection2
= Arrays.asList("merah",
"biru");
Collection<String> collection3
= Arrays.asList("kuning",
"hijau");
System.out.println(Collections.disjoint(collection1,
collection2));
System.out.println(Collections.disjoint(collection1,
collection3));
Metode frequency(collection, element)
menemukan jumlah kemunculan elemen di dalam koleksi. Sebagai contoh, frequency(koleksi, “merah”)
mengembalikan 2 di dalam kode berikut.
Collection<String> koleksi =
Arrays.asList("merah",
"kuning", "merah");
System.out.println(Collections.frequency(koleksi,
"merah"));
8.7 Kinerja Set dan List
Sekarang
akan dilakukan eksperimen untuk menguji kinerja set dan list. Kode8.8
menyajikan suatu program yang menunjukkan waktu eksekusi dalam menambah dan
menghapus elemen-elemen di dalam suatu set hash, set hash berantai, set tree,
list array, dan list berantai.
Kode8.8 UjiKinerjaSetList.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
import java.util.*;
public class UjiKinerjaSetList {
public static void main(String[]
args) {
// Menciptakan suatu set hash, dan menguji
kinerjanya
Collection<Integer> set1 = new HashSet<Integer>();
System.out.println("Waktu untuk
set hash adalah " +
dapatWaktuUji(set1, 500000) + " milidetik");
// Menciptakan suatu set hash berantai,
dan menguji kinerjanya
Collection<Integer> set2 = new
LinkedHashSet<Integer>();
System.out.println("Waktu untuk
set hash berantai adalah " +
dapatWaktuUji(set2, 500000) + " milidetik");
// Menciptakan suatu set tree, dan menguji
kinerjanya
Collection<Integer> set3 = new TreeSet<Integer>();
System.out.println("Waktu untuk
set tree adalah " +
dapatWaktuUji(set3, 500000) + " milidetik");
// Menciptakan suatu list array, dan
menguji kinerjanya
Collection<Integer> list1 = new
ArrayList<Integer>();
System.out.println("Waktu untuk
list array adalah " +
dapatWaktuUji(list1, 60000) + " milidetik");
// Menciptakan suatu list berantai, dan
menguji kinerjanya
Collection<Integer> list2 = new
LinkedList<Integer>();
System.out.println("Waktu untuk
list berantai adalah " +
dapatWaktuUji(list2, 60000) + " milidetik");
}
public static long dapatWaktuUji(Collection<Integer> c, int ukuran) {
long waktuMulai =
System.currentTimeMillis();
// Menambah angka 0, 1, 2, ..., ukuran - 1
ke dalam list array
List<Integer> list = new
ArrayList<Integer>();
for (int i = 0; i <
ukuran; i++)
list.add(i);
Collections.shuffle(list); // Mengacak list array
// Menambah elemen ke dalam kontainer
for (int elemen: list)
c.add(elemen);
Collections.shuffle(list); // Mengacak list array
// Menghapus elemen ke dalam kontainer
for (int elemen: list)
c.remove(elemen);
long waktuAkhir =
System.currentTimeMillis();
return waktuAkhir - waktuMulai; // Mengembalikan waktu eksekusi
}
}
|
Keluaran
Waktu untuk set hash adalah
2355 milidetik
Waktu untuk set hash
berantai adalah 2153 milidetik
Waktu untuk set tree adalah
3604 milidetik
Waktu untuk list array
adalah 11497 milidetik
Waktu untuk list berantai
adalah 16286 milidetik
Metode dapatWaktuUji menciptakan suatu list
integer yang berbeda dari 0 sampai ukuran-1
(baris 35-37), mengacak list (baris 39), menambah elemen-elemen dari list ke
kontainer c (baris 42-43), mengacak
list kembali (baris 45), menghapus elemen-elemen dari kontainer (baris 48-49),
dan terakhir mengembalikan waktu eksekusi (baris 52).
Program
menciptakan suatu set hash (baris 6), suatu set hash berantai (baris 11), suatu
set tree (baris 16), suatu list array (baris 21), dan suatu list berantai (baris
26). Program memperoleh waktu eksekusi untuk menambah dan menghapus 500000
elemen di dalam ketiga set dan menambah dan menghapus 60000 elemen di dalam
kedua list.
Seperti
yang Anda perhatikan, set lebih efisien dari list. Jika set cukup dan cocok untuk
aplikasi Anda, gunakan set. Bila Anda tidak memerlukan pengurutan di dalam
aplikasi, gunakan set hash.
8.8 Kelas Vector dan Stack
JCF
dikenalkan dengan JAVA 2. Beberapa struktur data yang didukung belakangan
adalah kelas Vector dan kelas Stack. Kedua kelas ini didesain-ulang
agar sesuai dengan JCF.
Vector
sama dengan ArrayList, kecuali bahwa
kelas Vector memuat beberapa metode
tersinkronisasi untuk mengakses dan memodifikasi vektor. Metode tersinkronisasi
tersebut dapat mencegah kerusakan atau korupsi data ketika suatu vektor diakses
dan dimodifikasi oleh dua atau lebih thread secara bersamaan. Pada banyak
aplikasi, hal ini tidak menjadi masalah dan tidak perlu. Penggunaan ArrayList lebih efisien daripada
penggunaan Vector.
Kelas Vector mengimplementasikan antarmuka List. Kelas ini juga mempunyai
metode-metode yang dimuat di dalam kelas Vector
awal yang didefinisikan sebelum kehadiran JAVA 2, seperti tertampil pada Gambar
8.9.
Gambar
8.9 Kelas Vector dalam JAVA 2 mengimplementasikan List dan juga memuat semua metode di dalam kelas Vector awal
Kebanyakan
metode-metode tambahan di dalam kelas Vector
yang dicantumkan di dalam diagram UML pada Gambar 8.9 sama dengan metode-metode
di dalam antarmuka List. Sebagai
contoh, addElement(Object element)
sama dengan metode add(Object element),
kecuali bahwa metode addElement
telah disinkronisasi. Gunakan ArrayList
jika Anda tidak membutuhkan sinkronisasi, karena ArrayList bekerja lebih cepat dari Vector.
Dalam
JCF, Stack diimplementasikan sebagai
suatu ekstensi dari Vector, seperti
diilustrasikan pada Gambar 8.10.
Gambar
8.10 Kelas Stack mewarisi Vector
untuk menyediakan struktur data dengan gaya FIFO (first-in, first-out)
Kelas Stack dikenalkan sebelum JAVA 2.
Metode-metode yang ditampilkan pada Gambar 8.10 digunakan sebelum JAVA 2.
Metode empty() sama dengan isEmpty(). Metode peek() menengok atau mengintip elemen teratas tumpukan tanpa
menghapusnya. Metode pop() menghapus
atau membuang elemen teratas dari tumpukan dan menjadikannya nilai balik.
Metode push(Object element)
memeriksa apakah elemen tertentu berada dalam tumpukan atau tidak.
8.9 Antrian dan Antrian Prioritas
Antrian
merupakan struktur data dengan gaya FIFO. Elemen disambungkan ke ujung antrian
dan dihapus dari awal antrian. Di dalam antrian prioritas, elemen-elemen
ditugasi prioritas. Ketika mengakses elemen, elemen dengan prioritas tertinggi
dihapus terlebih dahulu. Bagian ini akan mengenalkan antrian dan antrian
prioritas dalam JAVA API.
Antarmuka
Queue mewarisi java.lang.Collection dengan operasi-operasi tambahan untuk
menyisipkan, mengekstraksi, dan menginspeksi, seperti tertampil pada Gambar
8.11.
Metode offer digunakan untuk menambah suatu
elemen ke antrian. Metode ini sama dengan metode add dalam antarmuka Collection,
tetapi metode offer lebih sering
digunakan untuk antrian. Metode poll
dan remove sama, kecuali bahwa poll() mengembalikan null jika antrian kosong, sedangkan remove() akan melempar ekspesi pada
situasi itu. Metode peek dan element sama, kecuali bahwa peek() mengembalikan null jika antrian kosong, sedangkan element() akan melempar ekspesi pada
situasi itu.
Gambar
8.11 Antarmuka Queue mewarisi Collection
untuk menyediakan operasi-operasi tambahan seperti penyisipan, ekstraksi, dan
inspeksi.
8.9.1 Deque dan LinkedList
Kelas LinkedList mengimplementasikan
antarmuka Deque, yang mewarisi
antarmuka Queue, seperti tertampil
pada Gambar 8.12. Sehingga Anda bisa menggunakan LinkedList untuk menciptakan suatu antrian.
Gambar
8.12 LinkedList mengimplementasikan List
dan Deque
Deque mendukung
penyisipan dan penghapusan elemen pada kedua ujung antrian. Nama deque merupakan singkatan dari “double-ended queue” dan diucapkan dengan
“deck”. Antarmuka Deque mewarisi Queue
dengan beberapa metode tambahan untuk menyisipkan dan menghilangkan kedua ujung
antrian. Metode addFirst(e), removeFirst(), addLast(e), removeLast(),
getFirst(), dan getLast() didefinisikan di dalam antarmuka Deque.
Kode8.9
menunjukkan suatu contoh penggunaan antrian untuk menyimpan string. Baris 4
menciptakan suatu antrian menggunakan LinkedList.
Empat string ditambahkan ke dalam antrian pada baris 5-8. Metode size() yang didefinisikan di dalam
antarmuka Collection mengembalikan
jumlah elemen di dalam antrian (baris 10). Metode remove() mengambil dan menghapus elemen di kepala antrian (baris
11).
Kode8.9 UjiAntrian.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class UjiAntrian {
public static void main(String[]
args) {
java.util.Queue<String> antrian =
new java.util.LinkedList<String>();
antrian.offer("Aurora");
antrian.offer("Adam");
antrian.offer("Lizzy");
antrian.offer("Nicholaus");
while(antrian.size() > 0)
System.out.print(antrian.remove() +
" ");
}
}
|
Keluaran
Aurora Adam Lizzy Nicholaus
Kelas PriorityQueue mengimplementasikan suatu
antrian prioritas, seperti tertampil pada Gambar 8.13. Secara default, antrian
prioritas menata elemen-elemennya sesuai dengan urutan alamiah menggunakan Comparable. Elemen dengan nilai
terkecil ditugasi prioritas tertinggi, jadi dihapus dari antrian pertama kali.
Jika terdapat beberapa elemen dengan prioritas tertinggi yang sama, maka ikatan
berubah tak-beraturan. Anda juga bisa menspesifikasi suatu pengurutan
menggunakan Comparator di dalam konstruktor PriorityQueue-(initialCapacity, comparator).
Kode8.10
menunjukkan suatu contoh penggunaan antrian prioritas untuk menyimpan beberapa
string. Baris 5 menciptakan suatu antrian prioritas untuk menyimpan beberapa
string menggunakan konstruktor tanpa-argumen. Antrian prioritas ini menata
string sesuai urutan alamiah, sehingga string dihapus dari antrian dengan urutan
menaik. Baris 16-17 menciptakan suatu antrian prioritas menggunakan komparator
yang diperoleh dari Collections.reverse-
Order(), yang mengurutkan string secara terbalik, sehingga string dihapus
dari antrian secara menurun.
Gambar
8.13 Kelas PriorityQueue mengimplementasikan suatu antrian prioritas
Kode8.10 DemoAntrianPrioritas.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
import java.util.*;
public class DemoAntrianPrioritas {
public static void main(String[]
args) {
PriorityQueue<String> antrian1 = new
PriorityQueue<String>();
antrian1.offer("Gaby");
antrian1.offer("Artha");
antrian1.offer("Glory");
antrian1.offer("Philip");
System.out.println("Antrian
prioritas menggunakan Comparable:");
while (antrian1.size() > 0) {
System.out.print(antrian1.remove() +
" ");
}
PriorityQueue<String> antrian2 = new
PriorityQueue<String>(
4, Collections.reverseOrder());
antrian2.offer("Gaby");
antrian2.offer("Artha");
antrian2.offer("Glory ");
antrian2.offer("Philip");
System.out.println("\nAntrian
prioritas menggunakan komparator:");
while (antrian2.size() > 0) {
System.out.print(antrian2.remove() +
" ");
}
}
}
|
Keluaran
Antrian prioritas
menggunakan Comparable:
Artha Gaby Glory Philip
Antrian prioritas
menggunakan komparator:
Philip Glory Gaby Artha
8.10 Peta
Dimisalkan
program Anda menyimpan jutaan mahasiswa dan sangat sering melakukan pencarian
menggunakan NIK (nomor induk kependudukan). Struktur data yang efisien untuk
melakukan ini adalah peta atau map. Peta merupakan suatu kontainer yang
menyimpan elemen bersama dengan kunci. Kunci sama dengan indeks. Di dalam List, indeks adalah integer. Di dalam Map, kunci bisa berupa sembarang objek.
Suatu peta tidak bisa memuat kunci duplikat. Setiap kunci memetakan satu nilai.
Suatu kunci yang berpasangan dengan nilai membentuk suatu entri, yang disimpan
di dalam peta, seperti tertampil pada Gambar 8.14.
Gambar
8.14 Entri memuat sepasang
kunci/nilai, disimpan di dalam suatu peta
Terdapat
tiga jenis peta: HashMap, LinkedHashMap, dan TreeMap. Beberapa fitur bersama dari ketiga peta ini didefinisikan
di dalam antarmuka Map. Relasi
ketiganya ditampilkan pada Gambar 8.15.
Antarmuka
Map menyediakan beberapa metode
untuk queri, pembaruan, dan untuk mendapatkan koleksi nilai dan sehimpunan
kunci, seperti tertampil pada Gambar 8.16.
Gambar
8.15 Suatu peta menyimpan pasangan
kunci/nilai
Gambar
8.16 Antarmuka Map memetakan kunci kepada nilai
Beberapa
metode pembaru yang didefinisikan adalah termasuk clear, put, putAll, dan remove. Metode clear()
menghapus semua entri di dalam peta. Metode put(K key, V value) menghubungkan suatu nilai dengan suatu kunci di
dalam peta. Jika peta sebelumnya memuat suatu pemetaan untuk kunci ini, maka
nilai lama yang berkaitan dengan kunci tersebut yang dikembalikan atau
dijadikan nilai balik. Metode putAll(Map
m) menambah peta tertentu kepada peta ini. Metode remove(Object key) menghapus elemen peta untuk kunci tertentu dalam
peta.
Beberapa
metode queri yang didefinisikan termasuk containsKey,
containsValue, isEmpty, dan size.
Metode containsKey(Object key)
memeriksa apakah peta memiliki pemetaan untuk kunci tertentu. Metode containsValue(Object value) memeriksa
apakah peta memiliki pemetaan untuk nilai tertentu. Metode isEmpty() memeriksa apakah peta memiliki pemetaan atau tidak.
Metode size() mengembalikan jumlah
pemetaan di dalam peta.
Anda
bisa memperoleh suatu set kunci di dalam peta menggunakan metode keySet(), dan mendapatkan sekoleksi
nilai di dalam peta menggunakan metode values().
Metode entrySet() mengembalikan
suatu set objek yang mengimplementasikan antarmuka Map.Entry<K, V>, dimana Entry
merupakan antarmuka inner dari antarmuka Map,
seperti tertampil pada Gambar 8.17. Setiap objek di dalam set merupakan
sepasang kunci/nilai tertentu di dalam peta.
Gambar
8.17 Antarmuka Map.Entry beroperasi pada suatu entri di dalam peta
Kelas AbstractMap merupakan suatu kelas yang
mengimplementasikan semua metode di dalam antarmuka Map kecuali metode entrySet().
Gambar
8.18 JCF menyediakan tiga kelas peta
konkrit
Antarmuka
SortedMap mewarisi antarmuka Map untuk mempertahankan pemetaan
dengan urutan menaik dengan beberapa metode tambahan firstKey() dan lastKey()
untuk mengembalikan kunci terendah dan kunci tertinggi, metode headMap(toKey) untuk mengembalikan
bagian atau seporsi peta yang memiliki kunci lebih rendah dari toKey, metode tailMap(fromKey) untuk mengembalikan bagian atau seporsi peta yang
memiliki kunci lebih tinggi dari atau sama dengan fromKey.
Kelas HashMap, LinkedHashMap, dan TreeMap
merupakan tiga implementasi konkrit dari antarmuka Map, seperti tertampil pada Gambar 8.18.
Kelas HashMap efisien untuk melokasi suatu
nilai, menyisipkan suatu pemetaan, dan menghapus suatu pemetaan.
LinkedHashMap
mewarisi HashMap dengan suatu
implementasi link-berantai yang mendukung suatu pengurutan entri di dalam peta.
Entri di dalam suatu HashMap tidak
terurut, tetapi entri di dalam suatu LinkedHashMap
dapat diambil atau ditarik secara berurutan sesuai saat disisipkan ke dalam
peta (dikenal dengan urutan penyisipan) atau sesuai urutan terakhir kali
diakses (dikenal dengan urutan akses). Konstruktor tanpa-argumen menciptakan
suatu LinkedHashMap dengan urutan
penyisipan. Untuk menciptakan suatu LinkedHashMap
dengan urutan akses, digunakan LinkedHashMap(initialCapacity,
loadFactor, true).
Kelas TreeMap efisien untuk menjelajah kunci
dengan tatanan terurut. Kunci dapat diurutkan menggunakan antarmuka Comparable atau antarmuka Comparator. Jika Anda menciptakan suatu
TreeMap menggunakan konstruktor
tanpa-argumennya, metode compareTo
di dalam antarmuka Comparable
digunakan untuk membandingkan elemen-elemen di dalam peta, bila diasumsikan
bahwa kelas elemen meng-implementasikan antarmuka Comparable. Untuk menggunakan suatu komparator, Anda harus
menggunakan konstruktor TreeMap(Comparator
comparator) untuk menciptakan suatu peta terurut yang menggunakan metode compare di dalam komparator untuk
mengurutkan elemen di dalam peta berdasarkan kunci yang ada.
SortedMap
merupakan subantarmuka dari Map,
yang menjamin bahwa entri di dalam peta diurutkan. Subantarmuka ini juga
menyediakan metode firstKey() dan lastKey() untuk mengembalikan kunci
pertama dan kunci terakhir di dalam peta, dan metode headMap(toKey) dan tailMap(fromKey)
untuk mengembalikan seporsi atau bagian peta yang memiliki kunci lebih rendah
dari toKey dan lebih tinggi dari
atau sama dengan fromKey.
NavigableMap
mewarisi SortedMap untuk menyediakan
beberapa metode navigasi lowerKey(key),
floorKey(key), ceilingKey(key), dan higherKey(key)
yang mengembalikan kunci kurang dari, kurang dari atau sama dengan, lebih dari
atau sama dengan, dan lebih dari kunci yang diberikan (key) dan mengembalikan null bila tidak terdapat kunci yang dicari.
Metode pollFirstEntry() dan pollLastEntry() menghapus dan mengembalikan
entri pertama dan entri terakhir di dalam peta tree.
Kode8.11
menyajikan suatu contoh untuk menciptakan suatu peta hash, peta hash berantai,
dan peta tree yang memetakan mahasiswa pada umur. Program pertama-tama
menciptakan suatu peta hash dengan nama mahasiswa sebagai kunci dan umur
sebagai nilai. Program kemudian menciptakan suatu peta tree dari peta hash dan
menampilkan pemetaan dengan urutan kunci secara menaik. Terakhir, program
menciptakan suatu peta hash berantai, menambah entri ke dalam peta, dan
menampilkan entri-entri di dalam peta.
Kode8.11 UjiPeta.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
import java.util.*;
public class UjiPeta {
public static void main(String[]
args) {
// Menciptakan suatu HashMap
Map<String, Integer> hashMap = new HashMap<String,
Integer>();
hashMap.put("Sintong",
30);
hashMap.put("Munir", 31);
hashMap.put("Agung", 29);
hashMap.put("Nyoman",
29);
System.out.println("Menampilkan
entri di dalam HashMap");
System.out.println(hashMap +
"\n");
// Menciptakan suatu TreeMap dari HashMap
Map<String, Integer> treeMap=
new TreeMap<String, Integer>(hashMap);
System.out.println("Menampilkan
entri dengan urutan kunci menaik");
System.out.println(treeMap);
// Menciptakan suatu LinkedHashMap
Map<String, Integer> linkedHashMap =
new LinkedHashMap<String, Integer>(16, 0.75f, true);
linkedHashMap.put("Sintong",
30);
linkedHashMap.put("Munir",
31);
linkedHashMap.put("Agung",
29);
linkedHashMap.put("Nyoman",
29);
// Menampilkan umur untuk Agung
System.out.println("Umur
" + "Agung adalah " +
linkedHashMap.get("Agung").intValue());
System.out.println("\nMenampilkan
entri dalam LinkedHashMap");
System.out.println(linkedHashMap);
}
}
|
Keluaran
Menampilkan entri di dalam
HashMap
{Agung=29, Sintong=30,
Nyoman=29, Munir=31}
Menampilkan entri dengan
urutan kunci menaik
{Agung=29, Munir=31,
Nyoman=29, Sintong=30}
Umur Agung adalah 29
Menampilkan entri dalam
LinkedHashMap
{Sintong=30, Munir=31,
Nyoman=29, Agung=29}
Seperti
tertampil pada keluaran, urutan entri di dalam HashMap adalah acak. Entri di dalam TreeMap memiliki urutan kunci menaik. Entri di dalam LinkedHashMap berurutan sesuai dengan
akses, dari yang telah lama diakses sampai yang baru saja diakses.
Semua kelas
konkrit yang mengimplementasikan antarmuka Map
paling sedikit memiliki dua konstruktor. Satu adalah konstruktor tanpa-argumen
yang menciptakan suatu peta kosong, konstruktor yang lain adalah yang
menciptakan suatu peta dari instans Map.
Jadi, new TreeMap(String,
Integer)<hashMap> (baris 16-17) menciptakan suatu peta tree dari
suatu peta hash.
Anda
bisa menciptakan peta hash berantai dengan urutan akses atau urutan penyisipan.
Suatu peta hash berantai dengan urutan akses diciptakan pada baris 22-23. Entri
yang paling baru diakses ditempatkan di akhir peta. Entri dengan kunci Agung
diakses terakhir diakses pada baris 31, jadi ditempatkan di akhir peta pada
baris 34.
8.10.1 Studi Kasus: Jumlah Kemunculan
Kata
Studi
kasus ini menulis suatu program yang menghitung jumlah kemunculan kata di dalam
suatu teks dan menampilkan kata-kata dan frekuensi kemunculannya dengan urutan
alfabetikal. Program menggunakan suatu TreeMap
untuk menyimpan suatu entri yang memuat suatu kata dan frekuensi kemunculannya.
Untuk setiap kata, diperiksa apakah sudah dijadikan kunci di dalam peta atau
belum. Jika belum, kata tersebut sebagai kunci dan nilai 1 ditambahkan ke dalam
peta untuk membentuk suatu entri. Jika
sudah, nilai untuk kata tersebut (kunci) diinkremen sebanyak 1 di dalam peta.
Diasumsikan bahwa kata di dalam teks adalah case-insensitive, artinya tidak
membedakan antara huruf besar dengan huruf kecil. Kata Orang sama dengan kata orang.
Kode8.12 memberikan solusi terhadap permasalahan ini.
Kode8.12 HitungJumlahKemunculanKata.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
import java.util.*;
public class HitungJumlahKemunculanKata {
public static void main(String[]
args) {
// Menetapkan teks di dalam suatu string
String teks = "Teknik Elektro
Universitas Gadjah Mada " +
"Teknik Elektro Universitas
Mataram ";
// Menciptakan
TreeMap, menampung kata (kunci) dan
jumlah kemunculan (nilai)
TreeMap<String, Integer> peta = new TreeMap<String,
Integer>();
String[] kata = teks.split(" ");
for (int i = 0; i <
kata.length; i++) {
String kunci = kata[i].toLowerCase();
if (kunci.length() > 0) {
if (peta.get(kunci) == null) {
peta.put(kunci, 1);
}
else {
int nilai =
peta.get(kunci).intValue();
nilai++;
peta.put(kunci, nilai);
}
}
}
// Get all entries into a set
Set<Map.Entry<String, Integer>> entrySet = peta.entrySet();
// Get kunci and nilai from each entry
for (Map.Entry<String, Integer>
entry: entrySet)
System.out.println(entry.getValue() + "\t" + entry.getKey());
}
}
|
Keluaran
2 elektro
1 gadjah
1 mada
1 mataram
2 teknik
2 universitas
No comments:
Post a Comment