Mulakan dengan Java Collections Framework
JDK 1.2 memperkenalkan kerangka kerja baru untuk koleksi objek, yang disebut Java Collections Framework. "Oh tidak," anda mengerang, "bukan API lain, bukan kerangka lain untuk dipelajari!" Tetapi tunggu, sebelum anda berpaling, dengarkan saya: rangka Koleksi sepadan dengan usaha anda dan akan memberi banyak manfaat kepada pengaturcaraan anda. Tiga faedah besar segera muncul:
- Ini secara dramatik meningkatkan keterbacaan koleksi anda dengan menyediakan set antara muka standard untuk digunakan oleh banyak pengaturcara dalam banyak aplikasi.
- Ini menjadikan kod anda lebih fleksibel dengan membolehkan anda melewati dan mengembalikan antara muka dan bukannya kelas konkrit, menggeneralisasikan kod anda daripada menguncinya.
- Ia menawarkan banyak pelaksanaan khusus antara muka, yang membolehkan anda memilih koleksi yang paling sesuai dan menawarkan prestasi tertinggi untuk keperluan anda.
Dan itu hanya untuk permulaan.
Lawatan kerangka kerja kami akan dimulakan dengan gambaran keseluruhan kelebihan yang diberikannya untuk menyimpan set objek. Seperti yang anda akan ketahui, kerana rakan lama anda Hashtable
dan Vector
menyokong API baru, program anda akan seragam dan ringkas - sesuatu yang anda dan pembangun yang mengakses kod anda pasti akan gembira.
Selepas perbincangan awal kami, kami akan menggali lebih terperinci.
Kelebihan Java Collection: Gambaran keseluruhan
Sebelum Koleksi membuat debut yang paling dialu-alukan, kaedah standard untuk mengelompokkan objek Java adalah melalui array, the Vector
, dan Hashtable
. Ketiga-tiga koleksi ini mempunyai kaedah dan sintaks yang berbeza untuk mengakses ahli: tatasusunan menggunakan simbol kurungan persegi ([]), Vector
menggunakan elementAt
kaedah, dan Hashtable
penggunaan get
dan put
kaedah. Perbezaan ini telah lama menyebabkan pengaturcara menuju ketidakkonsistenan dalam melaksanakan koleksi mereka sendiri - ada yang meniru Vector
kaedah akses dan ada yang meniru Enumeration
antara muka.
Untuk merumitkan lagi masalah, kebanyakan Vector
kaedah ditandai sebagai akhir; iaitu, anda tidak boleh memanjangkan Vector
kelas untuk menerapkan koleksi yang serupa. Kami dapat membuat kelas koleksi yang tampak seperti Vector
dan bertindak seperti Vector
, tetapi tidak dapat diteruskan ke metode yang menggunakan Vector
parameter.
Akhirnya, tidak ada koleksi (array, Vector
atau Hashtable
) yang melaksanakan antara muka akses anggota standard. Semasa pengaturcara mengembangkan algoritma (seperti jenis) untuk memanipulasi koleksi, wacana yang hangat meletus mengenai objek apa yang harus disampaikan kepada algoritma. Sekiranya anda lulus array atau a Vector
? Sekiranya anda melaksanakan kedua-dua antara muka? Bercakap mengenai pendua dan kekeliruan.
Syukurlah, Java Collections Framework mengatasi masalah ini dan menawarkan sejumlah kelebihan daripada tidak menggunakan framework atau menggunakan Vector
dan Hashtable
:
Satu set antara muka koleksi yang boleh digunakan
Dengan melaksanakan salah satu antara muka asas -
Collection
,Set
,List
, atauMap
- anda memastikan Mematuhi kelas anda kepada API biasa dan menjadi lebih kerap dan mudah difahami. Oleh itu, sama ada anda menggunakan pangkalan data SQL, pencocokan warna, atau aplikasi sembang jarak jauh, jika anda melaksanakanCollection
antara muka, operasi pada koleksi objek anda sudah diketahui oleh pengguna anda. Antaramuka standard juga mempermudah pengiriman dan pengembalian koleksi ke dan dari kaedah kelas dan membolehkan kaedah tersebut berfungsi pada koleksi yang lebih luas.Satu set asas pelaksanaan koleksi
Selain yang dapat dipercaya
Hashtable
danVector
, yang telah diperbarui untuk menerapkanCollection
antarmuka, implementasi koleksi baru telah ditambahkan, termasukHashSet
danTreeSet
,ArrayList
danLinkedList
, danHashMap
danMap
. Menggunakan pelaksanaan yang ada dan biasa menjadikan kod anda lebih pendek dan lebih pantas untuk dimuat turun. Juga, menggunakan inti kod Java Core yang ada memastikan bahawa sebarang peningkatan pada kod asas juga akan meningkatkan prestasi kod anda.Tambahan berguna lain
Setiap koleksi kini mengembalikan
Iterator
, jenis yang lebih baikEnumeration
yang memungkinkan operasi elemen seperti penyisipan dan penghapusan. IniIterator
adalah "gagal cepat", yang bermaksud anda mendapat pengecualian jika senarai yang anda ikuti diubah oleh pengguna lain. Juga, koleksi berdasarkan senarai sepertiVector
mengembalikan aListIterator
yang membolehkan lelaran dan pengemaskinian dua arah.Beberapa koleksi (
TreeSet
danTreeMap
) secara tersirat menyokong pesanan. Gunakan kelas ini untuk mengekalkan senarai yang disusun tanpa usaha. Anda boleh menemui elemen terkecil dan terbesar atau melakukan carian binari untuk meningkatkan prestasi senarai besar. Anda boleh menyusun koleksi lain dengan menyediakan kaedah membandingkan koleksi (Comparator
objek) atau kaedah membandingkan objek (Comparable
antara muka).Akhirnya, kelas statik
Collections
menyediakan versi koleksi yang sedia ada yang tidak dapat diubah (baca sahaja) dan disegerakkan. Kelas yang tidak dapat diubah suai sangat berguna untuk mengelakkan perubahan pada koleksi yang tidak diingini. Versi koleksi yang disegerakkan adalah keperluan untuk program multithreaded.
Java Collections Framework adalah sebahagian daripada Core Java dan terkandung dalam java.util.collections
paket JDK 1.2. Rangka kerja ini juga tersedia sebagai pakej untuk JDK 1.1 (lihat Sumber).
Catatan: Koleksi versi JDK 1.1 diberi nama com.sun.java.util.collections
. Perlu diingat bahawa kod yang dikembangkan dengan versi 1.1 mesti dikemas kini dan dikompilasi ulang untuk versi 1.2, dan sebarang objek yang bersiri dalam 1.1 tidak dapat didesialisasikan menjadi 1.2.
Marilah kita melihat lebih dekat kelebihan ini dengan menggunakan Java Collections Framework dengan beberapa kod kita sendiri.
API yang baik
Kelebihan pertama Java Collections Framework adalah API yang konsisten dan tetap. API ini termaktub dalam satu set asas antara muka, Collection
, Set
, List
, atau Map
. The Collection
muka mengandungi operasi koleksi asas seperti menambah, membuang, dan ujian untuk menjadi ahli (membendung). Sebarang pelaksanaan koleksi, sama ada yang disediakan oleh Java Collections Framework atau salah satu ciptaan anda sendiri, akan menyokong salah satu antara muka ini. Kerana kerangka Koleksi tetap dan konsisten, anda akan mempelajari sebahagian besar kerangka hanya dengan mempelajari antara muka ini.
Kedua Set
- duanya dan List
melaksanakan Collection
antara muka. Yang Set
antara muka adalah sama dengan Collection
antara muka kecuali kaedah tambahan, toArray
yang menukarkan Set
kepada Object
tatasusunan. Yang List
antara muka juga melaksanakan Collection
antara muka, tetapi menyediakan banyak Pengakses yang menggunakan indeks integer ke dalam senarai. Sebagai contoh, get
, remove
, dan set
semua mengambil integer yang memberi kesan kepada elemen diindeks dalam senarai. Yang Map
antara muka bukan berasal dari koleksi, tetapi menyediakan antara muka yang serupa dengan kaedah java.util.Hashtable
. Kekunci digunakan untuk meletakkan dan mendapatkan nilai. Setiap antara muka ini dijelaskan dalam contoh kod berikut.
Segmen kod berikut menunjukkan cara melakukan banyak Collection
operasi HashSet
, koleksi asas yang menggunakan Set
antara muka. A HashSet
hanyalah sekumpulan yang tidak membenarkan unsur pendua dan tidak menyusun atau meletakkan elemennya. Kod menunjukkan bagaimana anda membuat koleksi asas dan menambah, membuang, dan menguji elemen. Kerana Vector
kini menyokong Collection
antara muka, anda juga boleh melaksanakan kod ini pada vektor, yang anda boleh menguji dengan menukar HashSet
pengakuan dan pembina kepada Vector
.
import java.util.collections. *; kelas awam CollectionTest {// Statics public static void main (String [] args) {System.out.println ("Test Collection"); // Buat koleksi HashSet koleksi = HashSet baru (); // Menambah String dog1 = "Max", dog2 = "Bailey", dog3 = "Harriet"; koleksi.add (dog1); koleksi.add (dog2); koleksi.add (dog3); // Sizing System.out.println ("Koleksi dibuat" + ", size =" + collection.size () + ", isEmpty =" + collection.isEmpty ()); // Containment System.out.println ("Koleksi mengandungi" + dog3 + ":" + collection.contains (dog3)); // Pengulangan. Iterator menyokong hasNext, seterusnya, hapus System.out.println ("Iterasi koleksi (tidak disusun):"); Iterator iterator = koleksi.iterator (); semasa (iterator.hasNext ()) System.out.println ("" + iterator.next ()); // Mengeluarkan koleksi.hapus (dog1); koleksi.kelas (); }}
Sekarang mari kita membina pengetahuan asas kami mengenai koleksi dan melihat antara muka dan pelaksanaan lain dalam Kerangka Koleksi Java.
Pelaksanaan konkrit yang baik
Kami telah menggunakan Collection
antara muka pada koleksi konkrit, yang HashSet
. Sekarang mari kita lihat set lengkap pelaksanaan koleksi konkrit yang disediakan dalam kerangka Java Collections (Lihat bahagian Sumber untuk pautan ke garis besar penjelasan Java dari kerangka Java Collections.)
Pelaksanaan | ||||||
---|---|---|---|---|---|---|
Jadual Hash | Array boleh ubah saiz | Pokok Seimbang (Disusun) | Senarai Terpaut | Warisan | ||
Antara muka | Tetapkan | HashSet | * | Set Pokok | * | * |
Senaraikan | * | Senarai Array | * | Senarai Terpaut | Vektor | |
Peta | Peta Hash | * | Peta Pokok | * | Meja Hashash |
Implementations marked with an asterix (*) make no sense or provide no compelling reason to implement. For instance, providing a List
interface to a Hash Table makes no sense because there is no notion of order in a Hash Table. Similarly, there is no Map
interface for a Linked List because a list has no notion of table lookup.
Let's now exercise the List
interface by operating on concrete implementations that implement the List
interface, the ArrayList
, and the LinkedList
. The code below is similar to the previous example, but it performs many List
operations.
import java.util.collections.*; public class ListTest { // Statics public static void main( String [] args ) { System.out.println( "List Test" ); // Create a collection ArrayList list = new ArrayList(); // Adding String [] toys = { "Shoe", "Ball", "Frisbee" }; list.addAll( Arrays.toList( toys ) ); // Sizing System.out.println( "List created" + ", size=" + list.size() + ", isEmpty=" + list.isEmpty() ); // Iteration using indexes. System.out.println( "List iteration (unsorted):" ); for ( int i = 0; i < list.size(); i++ ) System.out.println( " " + list.get( i ) ); // Reverse Iteration using ListIterator System.out.println( "List iteration (reverse):" ); ListIterator iterator = list.listIterator( list.size() ); while ( iterator.hasPrevious() ) System.out.println( " " + iterator.previous() ); // Removing list.remove( 0 ); list.clear(); } }
As with the first example, it's simple to swap out one implementation for another. You can use a LinkedList
instead of an ArrayList
simply by changing the line with the ArrayList
constructor. Similarly, you can use a Vector
, which now supports the List
interface.
When deciding between these two implementations, you should consider whether the list is volatile (grows and shrinks often) and whether access is random or ordered. My own tests have shown that the ArrayList
generally outperforms the LinkedList
and the new Vector
.
Notice how we add elements to the list: we use the addAll
method and the static method Arrays.toList
. This static method is one of the most useful utility methods in the Collections framework because it allows any array to be viewed as a List
. Now an array may be used anywhere a Collection
is needed.
Notice that I iterate through the list via an indexed accessor, get
, and the ListIterator
class. In addition to reverse iteration, the ListIterator
class allows you to add, remove, and set any element in the list at the point addressed by the ListIterator
. This approach is quite useful for filtering or updating a list on an element-by-element basis.
Antara muka asas terakhir dalam Java Collections Framework adalah Map
. Antaramuka ini dilaksanakan dengan dua implementasi konkrit baru, the TreeMap
dan the HashMap
. Ini TreeMap
adalah pelaksanaan pokok seimbang yang menyusun elemen mengikut kunci.
Mari kita gambarkan penggunaan Map
antara muka dengan contoh mudah yang menunjukkan cara menambah, membuat pertanyaan, dan membersihkan koleksi. Contoh ini, yang menggunakan HashMap
kelas, tidak jauh berbeza dengan cara kita menggunakan Hashtable
sebelum rangka kerja Koleksi. Sekarang, dengan kemas kini Hashtable
untuk menyokong Map
antara muka, anda dapat menukar garis yang memberi contoh HashMap
dan menggantinya dengan contoh Hashtable
.