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 Hashtabledan Vectormenyokong 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 ([]), Vectormenggunakan elementAtkaedah, dan Hashtablepenggunaan getdan putkaedah. Perbezaan ini telah lama menyebabkan pengaturcara menuju ketidakkonsistenan dalam melaksanakan koleksi mereka sendiri - ada yang meniru Vectorkaedah akses dan ada yang meniru Enumerationantara muka.

Untuk merumitkan lagi masalah, kebanyakan Vectorkaedah ditandai sebagai akhir; iaitu, anda tidak boleh memanjangkan Vectorkelas untuk menerapkan koleksi yang serupa. Kami dapat membuat kelas koleksi yang tampak seperti Vectordan bertindak seperti Vector, tetapi tidak dapat diteruskan ke metode yang menggunakan Vectorparameter.

Akhirnya, tidak ada koleksi (array, Vectoratau 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 Vectordan Hashtable:

  • Satu set antara muka koleksi yang boleh digunakan

    Dengan melaksanakan salah satu antara muka asas - Collection, Set, List, atau Map- 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 melaksanakan Collectionantara 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 Hashtabledan Vector, yang telah diperbarui untuk menerapkan Collectionantarmuka, implementasi koleksi baru telah ditambahkan, termasuk HashSetdan TreeSet, ArrayListdan LinkedList, dan HashMapdan Map. 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 baik Enumerationyang memungkinkan operasi elemen seperti penyisipan dan penghapusan. Ini Iteratoradalah "gagal cepat", yang bermaksud anda mendapat pengecualian jika senarai yang anda ikuti diubah oleh pengguna lain. Juga, koleksi berdasarkan senarai seperti Vectormengembalikan a ListIteratoryang membolehkan lelaran dan pengemaskinian dua arah.

    Beberapa koleksi ( TreeSetdan TreeMap) 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 ( Comparatorobjek) atau kaedah membandingkan objek ( Comparableantara muka).

    Akhirnya, kelas statik Collectionsmenyediakan 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.collectionspaket 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 Collectionmuka 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 Listmelaksanakan Collectionantara muka. Yang Setantara muka adalah sama dengan Collectionantara muka kecuali kaedah tambahan, toArrayyang menukarkan Setkepada Objecttatasusunan. Yang Listantara muka juga melaksanakan Collectionantara muka, tetapi menyediakan banyak Pengakses yang menggunakan indeks integer ke dalam senarai. Sebagai contoh, get, remove, dan setsemua mengambil integer yang memberi kesan kepada elemen diindeks dalam senarai. Yang Mapantara 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 Collectionoperasi HashSet, koleksi asas yang menggunakan Setantara muka. A HashSethanyalah 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 Vectorkini menyokong Collectionantara muka, anda juga boleh melaksanakan kod ini pada vektor, yang anda boleh menguji dengan menukar HashSetpengakuan 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 Collectionantara 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 TreeMapdan the HashMap. Ini TreeMapadalah pelaksanaan pokok seimbang yang menyusun elemen mengikut kunci.

Mari kita gambarkan penggunaan Mapantara muka dengan contoh mudah yang menunjukkan cara menambah, membuat pertanyaan, dan membersihkan koleksi. Contoh ini, yang menggunakan HashMapkelas, tidak jauh berbeza dengan cara kita menggunakan Hashtablesebelum rangka kerja Koleksi. Sekarang, dengan kemas kini Hashtableuntuk menyokong Mapantara muka, anda dapat menukar garis yang memberi contoh HashMapdan menggantinya dengan contoh Hashtable.