} }
kalau kita eksekusi kode di atas maka customer akan diurutkan berdasarkan idnya, seperti di bawah ini :
$ javac CustomerTreeSetTest.java Customer.java $ java CustomerTreeSetTest
keranjang no-372 idnya:1 keranjang no-373 idnya:2 $
TreeSet dan TreeMap menyaratkan item yang dimasukkan mengimplementasikan Comparable, atau kalau itemnya tidak bisa mengimplementasikan Comparable, kita harus menyediakan class yang mengimplementasikan Comparator dan memasukkan object dari class Comparator tersebut di constructor dari TreeSet atau TreeMap, seperti cuplikan kode di bawah ini :
Set<Customer> customers = new TreeSet<Customer>(new CustomerComparator()); Map<Customer> customerMap = new TreeMap<Customer>(new CustomerComparator());
Kedua collection ini akan menyusun item dalam keadaan terurut menggunakan struktur data tree, kalau item yang dimasukkan lebih kecil dari root maka diletakkan di tree sebelah kiri, kalau lebih besar diletakkan di sebelah kanan. Algoritma seperti ini menyebabkan proses penambahan item baru ke dalam collection menjadi sedikit lebih lambat daripada HashSet. Tetapi ketika isi dari TreeSet diambil, keadaanya sudah dalam kondisi terurut, sehingga tidak diperlukan proses pengurutan lagi.
Jenis collection yang bersifat terurut hanya tersedia untuk Set dan Map, sedangkan untuk List tidak ada. Nah kalau kita ingin membuat sebuah List terurut kita bisa menggunakan class Collections yang di dalamnya terdapat method yang bisa mengurutkan List. Kita akan membahas tentang class Collections di bab selanjutnya.
Class Collections dan Class Arrays
Class Collections berisi method-method utility yang digunakan antara lain untuk: melakukan sorting, melakukan pencarian, mengacak isi List, membalik susunan List, mengcopy potongan List, mengisi list dengan pola tertentu dan seterusnya. Kita akan membahas satu per satu method di atas.
Method sort digunakan untuk mengurutkan List berdasarkan logika yang ada dalam method Comparable. Item di dalam List harus mengimplementasikan interface Comparable, kalau tidak maka gunakan method sort dengan dua parameter: List dan Object dari class yang mengimplementasikan interface Comparator, contoh potongan kodenya seperti di bawah ini :
import java.util.List; import java.util.ArrayList; import java.util.Collections;
public class SortListTest {
public static void main(String[] args){
List<Customer> customers = new ArrayList<Customer>(); Customer cust1 = new Customer();
cust1.setId(10l); customers.add(cust1);
Customer cust2 = new Customer(); cust2.setId(2l);
customers.add(cust2);
Customer cust3 = new Customer(); cust3.setId(5l);
customers.add(cust3);
System.out.println("isi dari list sebelum disorting: "); for(int i=0; i< customers.size();i++) {
System.out.println("index ke-" + i + ":" + customers.get(i) ); }
Collections.sort(customers);
System.out.println("isi dari list setelah disorting: "); for(int i=0; i< customers.size();i++) {
System.out.println("index ke-" + i + ":" + customers.get(i) ); }
} }
Kode di atas memperlihatkan bahwa kita membuat List of Customer dengan id yang tidak terurut, karena Customer mengimplementasikan interface Comparable maka isi dari List of Customer tersebut bisa disorting menggunakan method sort dari class Collections. Kalau kode di atas docompile dan dieksekusi hasilnya adalah :
$ javac SortListTest.java Customer.java $ java SortListTest
isi dari list sebelum disorting: index ke-0:10
index ke-1:2 index ke-2:5
isi dari list setelah disorting: index ke-0:2
index ke-1:5 index ke-2:10 $
Kalau misalnya Customer tidak mengimplementasikan interface Comparable, maka kita bisa membuat class CustomerComparator yang mengimplementasikan interface Comparator sebagai pembanding antara dua buah Customer mana yang lebih besar, kode di atas bisa diedit sebagian dengan memanggil method sort yang mempunyai dua buah parameter: List of Customer dan instance dari CustomerComparator.
Collections.sort(customers, new CustomerComparator());
Method binarySearch digunakan untuk melakukan pencarian terhadap isi List dengan lebih cepat dibanding dengan method indexOf dari interface List. Method binarySearch baru bisa dipanggil setelah List disorting dahulu. Method binarySearch memerlukan dua parameter kalau object dalam List mengimplementasikan interface Comparable: Listnya dan item yang ingin dicari. Contoh kode penggunaan method binarySearch adalah :
import java.util.List; import java.util.ArrayList; import java.util.Collections; public class BinarySearchTest {
public static void main(String[] args){
Customer cust1 = new Customer(); cust1.setId(10l);
customers.add(cust1);
Customer cust2 = new Customer(); cust2.setId(2l);
customers.add(cust2);
Customer cust3 = new Customer(); cust3.setId(5l);
customers.add(cust3); Collections.sort(customers);
int index = Collections.binarySearch(customers, cust3); System.out.println("Customer dengan id:" + cust3.getId() + " ditemukan di index : " + index);
} }
hasil eksekusi kode di atas adalah sebagai berikut : $ javac BinarySearchTest.java Customer.java $ java BinarySearchTest
Customer dengan id:5 ditemukan di index : 1 $
Kalau item tidak mengimplementasikan interface Comparable maka method binarySearch memerlukan tiga parameter: List, item yang dicari dan object dari class Comparator, seperti dalam kode berikut ini :
int index = Collections.binarySearch(customers, cust3, new CustomerComparator());
Untuk mengacak isi dari sebuah list, ada method shufe. Method shufe ada dua overload, yang pertama hanya mempunyai satu parameter berupa List, yang kedua mempunyai dua buah parameter: List dan object dari class Random. Object Random digunakan untuk menentukan jenis randomisasi yang ingin digunakan untuk mengacak isi dari List.
Method reverse digunakan untuk membalik isi dari List, dimana yang depan menjadi di belakang dan sebaliknya. Penggunaan method ini perlu hati-hati karena kecepatanya linier, semakin banyak isi dari List waktu eksekusinya membesar secara linier.
Method copy digunakan untuk mengcopy isi dari satu List ke List lain, method ini cukup praktis dibanding harus melakukan copy manual yang memerlukan proses iterasi, jadi hemat kira-kira empat sampai lima baris kode.
Method fll digunakan untuk mengganti isi dari sebuah list dengan sebuah object yang sama. Parameter method fll ada dua : List dan object item yang akan digunakan untuk menimpa semua item yang ada dalam List.
Method min dan max digunakan untuk mendapatkan nilai maximum dan minimum dari sebuah List. Method ini menyaratkan semua item di dalam List harus mengimplementasikan interface Comparable. Seperti biasa, kalau item di dalam List tidak mengimplementasikan interface Comparable maka kita harus menambahkan instance dari class yang mengimplementasikan interface Comparator ke dalam method min dan max.
Ada satu jenis method yang cukup berguna, yaitu unmodifable, jenis method ini ada beberapa, antara lain: unmodifableList, unmodifableMap, unmodifableSet dan unmodifableCollection. Method jenis ini bagus sekali kalau digunakan untuk melindungi collection agar tidak bisa dimodifkasi, artinya collectionnya akan bersifat read only. Misalnya di dalam suatu class kita punya property yang bertipe collection, nah kita tidak ingin collection ini dimodifkasi di luar dari class, sehingga setiap kali method ini digunakan sebagai return type, yang kita return adalah versi read only dari collection tersebut. Sebagai contoh, kita modifkasi sedikit class Customer agar mempunyai property emails yang bertipe List of String, seperti di bawah ini :
import java.lang.Comparable; import java.util.List; import java.util.ArrayList;
import java.util.Collections;
public class Customer implements Comparable<Customer>{ private Long id;
private List<String> emails; public void setId(Long aId){ this.id = aId;
}
public Long getId() { return this.id; }
public void setEmails(List<String> aEmails) { this.emails = aEmails;
}
public List<String> getEmails() {
return Collections.unmodifiableList(emails); }
public void addEmail(String email){ if(this.emails == null) {
this.emails = new ArrayList<String>(); }
emails.add(email); }
public int compareTo(Customer c) { return getId().compareTo(c.getId()); }
public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; }
final Customer other = (Customer) obj;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) { return false;
}
return true; }
public int hashCode() { int hash = 7;
hash = 53 * hash + (this.id != null ? this.id.hashCode() : 0); return hash;
} }
Dari kode di atas, terlihat bahwa pada saat method getEmails dipanggil, yang dikembalikan adalah versi read only dari emails. Dengan begitu, emails hanya bisa dimodifkasi dari dalam class Customer dengan memanggil method addEmail. Praktek seperti ini sangat disarankan terutama ketika kita membuat kode yang banyak digunakan orang lain dan tidak ingin collection yang dimanage oleh library tersebut diedit sembarangan. Pengaturan seperti ini biasanya cukup ditekankan kalau aplikasi dibuat oleh banyak sekali orang, sehingga bisa meminimalisasi kesalahan karena kurangnya informasi atau ketidaktahuan anggota tim lain. Dengan membuat collection yang ditandai dengan read only seperti di atas, kita menyampaikan informasi kepada orang lain yang mungkin menggunakan class Customer ini bahwa List emails tidak bisa diedit dari luar class Customer.
Class Arrays berisi method-method utility untuk bekerja dengan array, sama seperti class Collections yang berisi method-method utility untuk bekerja dengan collection. Method yang ada dalam class Arrays kurang lebih sama dengan method yang ada dalam class Collections,
seperti: proses sorting, pencarian, mengisi array dengan nilai tertentu, membuat copy dari array, memeriksa apakah dua buah array sama persis, mendapatkan nilai hashCode dari array, mendapatkan toString dari array dan merubah array menjadi List dengan cepat.
Method asList digunakan untuk mengubah array menjadi List dengan cepat. Tanpa bantuan method ini merubah array menjadi List memerlukan langkah-langkah : membuat instance dari List, kemudian mengkopy isi array ke dalam List dengan iterasi. Langkah-langkah di atas kira-kira memerlukan lima baris kode, tetapi dengan menggunakan method asList cukup satu baris kode saja.
Tanpa menggunakan method asList mengcopy array ke dalam List kodenya seperti di bawah ini : import java.util.List;
import java.util.ArrayList;
public class CopyArrayManualTest {
public static void main(String[] args) { String[] names = {"me","you","they","us"}; List<String> nameList = new ArrayList<String>(); for(int i = 0; i < names.length; i++) {
nameList.add(names[i]);
System.out.println("name:" + names[i]); }
} }
Dengan menggunakan class Arrays kode di atas menjadi sangat pendek, seperti di bawah ini : import java.util.List;
import java.util.Arrays; public class CopyArrayTest {
public static void main(String[] args) { String[] names = {"me","you","they","us"}; List<String> nameList = Arrays.asList(names); }
}
Method equals digunakan untuk menentukan apakah dua buah array isinya sama persis atau tidak, method ini sangat praktis digunakan daripada melakukan iterasi satu per satu isi dari array dan membandingkanya dengan isi array lain.
Method toString bisa digunakan untuk membuat sebuah string representasi dari array, string ini sudah diformat sekian rupa sehingga kalau diprint di dalam console akan terlihat bagus. Tanpa menggunakan method toString ini biasanya kita melakukan iterasi untuk mencetak satu persatu isi dari array, dengan adanya method ini tidak perlu lagi melakukan iterasi hanya untuk menampilkan array ke dalam console.
Method copyOf digunakan untuk mengcopy sebagian, keseluruhan atau malah membuat array baru dengan isi yang sama tetapi ukurannya lebih panjang dari sebuah array. Sedangkan method copyOfRange digunakan untuk mengcopy sebagian dari array dengan mendefnisikan awal dari index dan akhir dari index yang ingin dicopy. Perhatikan contoh berikut ini :
import java.util.Arrays;
public class CopyPartialArrayTest {
public static void main(String[] args) { String[] names = {"me","you","they","us"};
//membuat array baru dari sebagian isi array names String[] n = Arrays.copyOf(names, 2);
System.out.println("setelah dipotong : " + Arrays.toString(n)); //membuat array baru dari semua isi array names
//sekaligus panjangnya bertambah n = Arrays.copyOf(names, 7);
System.out.println("setelah ditambah panjang : " + Arrays.toString(n)); //copy sebagian isi array names dari index 1 sampai index 3
n = Arrays.copyOfRange(names, 1, 3);
System.out.println("setelah dipotong : " + Arrays.toString(n)); //copy sebagian isinya dan tambahkan default value untuk sisanya n = Arrays.copyOfRange(names, 2, 10);
System.out.println("setelah dipotong dan bertambah panjang: " + Arrays.toString(n));
} }
Coba tebak hasil eksekusi kode di atas! Apakah tebakanya sama dengan hasil eksekusinya seperti di bawah ini ?
$ javac CopyPartialArrayTest.java $ java CopyPartialArrayTest setelah dipotong : [me, you]
setelah ditambah panjang : [me, you, they, us, null, null, null] setelah dipotong : [you, they]
setelah dipotong dan bertambah panjang: [they, us, null, null, null, null, null, null]
$
Sisanya, method-metthod seperti : sort dan binarySearch sama persis penggunaanya dengan method yang ada dalam class Collections.