Започнете с Java Collections Framework

JDK 1.2 въвежда нова рамка за колекции от обекти, наречена Java Collections Framework. "О, не", пъшкате вие, "нито друг API, нито друга рамка за учене!" Но изчакайте, преди да се обърнете, чуйте ме: рамката Collections си струва усилията и ще бъде от полза за програмирането ви по много начини. Три големи предимства идват веднага на ум:

  • Това драстично увеличава четливостта на вашите колекции, като предоставя стандартен набор от интерфейси, които да се използват от много програмисти в много приложения.
  • Това прави вашия код по-гъвкав, като ви позволява да предавате и връщате интерфейси вместо конкретни класове, обобщавайки кода си, вместо да го заключвате.
  • Той предлага много специфични изпълнения на интерфейсите, което ви позволява да изберете най-подходящата колекция и предлага най-висока производителност за вашите нужди.

И това е само за начало.

Нашата обиколка на рамката ще започне с преглед на предимствата, които тя предоставя за съхранение на комплекти обекти. Както скоро ще откриете, тъй като старите ви приятели на работния кон Hashtableи Vectorподдържат новия API, вашите програми ще бъдат еднакви и кратки - нещо, за което вие и разработчиците, достъпващи вашия код, със сигурност ще се радват.

След предварителната ни дискусия ще се задълбочим в детайлите.

Предимството на Java Collections: Общ преглед

Преди Collections да направи своя най-добре дошъл дебют, стандартните методи за групиране на Java обекти бяха чрез масива, the Vectorи Hashtable. И трите от тези колекции имат различни методи и синтаксис за достъп до членове: масивите използват квадратните скоби ([]), Vectorизползват elementAtметода и Hashtableизползват getи putметоди. Тези разлики отдавна водят програмистите по пътя към непоследователност при прилагането на собствените им колекции - някои емулират Vectorметодите за достъп, а други емулират Enumerationинтерфейса.

За допълнително усложняване на нещата повечето Vectorметоди са маркирани като окончателни; тоест не можете да разширите Vectorкласа, за да приложите подобен тип колекция. Можем да създадем клас на колекция, който изглеждаше като a Vectorи действаше като a Vector, но не можеше да бъде предаден на метод, който приема Vectorпараметър като a.

И накрая, нито една от колекциите (масив Vectorили Hashtable) не изпълнява стандартен интерфейс за достъп на членове. Докато програмистите разработваха алгоритми (като сортове) за манипулиране на колекции, избухна разгорещен дискурс за това кой обект да се предаде на алгоритъма. Трябва ли да предадете масив или a Vector? Трябва ли да внедрите и двата интерфейса? Говорете за дублиране и объркване.

За щастие, Java Collections Framework отстранява тези проблеми и предлага редица предимства пред използването на никаква рамка или използването на Vectorи Hashtable:

  • Използваем набор от интерфейси за събиране

    С реализацията на един от основните интерфейси - Collection, Set, List, или Map- можете да си осигурите клас е съобразена с обща API и става все по-редовно и лесно разбираема. Така че, независимо дали внедрявате SQL база данни, съвпадение на цветни образци или приложение за отдалечен чат, ако внедрите Collectionинтерфейса, операциите върху вашата колекция от обекти са добре познати на вашите потребители. Стандартните интерфейси също опростяват предаването и връщането на колекции към и от методите на класа и позволяват на методите да работят върху по-голямо разнообразие от колекции.

  • Основен набор от реализации на колекции

    В допълнение към надеждните Hashtableи Vector, които са актуализирани, за да внедрят Collectionинтерфейсите, са добавени нови реализации на колекции, включително HashSetи TreeSet, ArrayListи LinkedList, и HashMapи Map. Използването на съществуваща, обща реализация прави вашия код по-кратък и по-бърз за изтегляне. Също така, използването на съществуващо ядро ​​на Core Java гарантира, че всякакви подобрения в основния код също ще подобрят производителността на вашия код.

  • Други полезни подобрения

    Всяка колекция сега връща Iteratorподобрен тип, Enumerationкойто позволява операции с елементи като вмъкване и изтриване. Това Iteratorе „бързо-неуспешно“, което означава, че получавате изключение, ако списъкът, който итерирате, се промени от друг потребител. Също така колекциите, базирани на списък, като например Vectorвръщат a, ListIteratorкоито позволяват двупосочна итерация и актуализиране.

    Няколко колекции ( TreeSetи TreeMap) имплицитно поддържат подреждането. Използвайте тези класове, за да поддържате сортиран списък без усилия. Можете да намерите най-малките и големи елементи или да извършите двоично търсене, за да подобрите ефективността на големите списъци. Можете да сортирате други колекции, като предоставите метод за сравнение на колекция ( Comparatorобект) или метод за сравнение на обекти ( Comparableинтерфейс).

    И накрая, статичният клас Collectionsпредоставя немодифицируеми (само за четене) и синхронизирани версии на съществуващи колекции. Немодифицируемите класове са полезни за предотвратяване на нежелани промени в колекция. Синхронизираната версия на колекция е необходимост за многонишкови програми.

Рамката на Java Collections е част от Core Java и се съдържа в java.util.collectionsпакета на JDK 1.2. Рамката се предлага и като пакет за JDK 1.1 (вж. Ресурси).

Забележка: Името на версията на колекциите JDK 1.1 com.sun.java.util.collections. Имайте предвид, че кодът, разработен с версия 1.1, трябва да бъде актуализиран и прекомпилиран за версия 1.2 и всички обекти, сериализирани в 1.1, не могат да бъдат десериализирани в 1.2.

Нека сега разгледаме по-отблизо тези предимства, като упражняваме Java Collections Framework с някакъв собствен код.

Добър API

Първото предимство на Java Collections Framework е последователен и редовен API. Този интерфейс е кодифицирано в основен набор от интерфейси, Collection, Set, List, или Map. В Collectionинтерфейс съдържа основни операции по събиране като например добавяне, премахване и тестове за членство (задържане). Всяко внедряване на колекция, независимо дали е такава, предоставена от Java Collections Framework или някое от вашите собствени творения, ще поддържа един от тези интерфейси. Тъй като рамката Collections е редовна и последователна, вие ще научите голяма част от рамките просто като научите тези интерфейси.

И двете, Setи Listприлагат Collectionинтерфейса. В Setинтерфейса е идентичен с Collectionинтерфейс с изключение на допълнителен метод toArray, който преобразува Setдо Objectмасив. В Listинтерфейса също реализира Collectionинтерфейс, но предлага много средства за достъп, които използват индекс цяло число в списъка. Например get, removeи setвсички вземат цяло число, което се отразява на индексираната елемент в списъка. В Mapинтерфейс не е получен от събиране, но осигурява интерфейс подобен на методите в java.util.Hashtable. Клавишите се използват за поставяне и получаване на стойности. Всеки от тези интерфейси е описан в следващите кодови примери.

Следващият сегмент на кода демонстрира как да се изпълняват много Collectionоперации HashSet, основна колекция, която реализира Setинтерфейса. A HashSetе просто набор, който не позволява дублиращи се елементи и не подрежда или позиционира своите елементи. Кодът показва как създавате основна колекция и добавяте, премахвате и тествате за елементи. Тъй като Vectorсега поддържа Collectionинтерфейса, можете също да изпълните този код върху вектор, който можете да тествате, като промените HashSetдекларацията и конструктора на a Vector.

импортиране на java.util.collections. *; публичен клас CollectionTest {// Статика публична статична void main (String [] args) {System.out.println ("Тест на колекция"); // Създаване на колекция HashSet колекция = нов HashSet (); // Добавяне на низ dog1 = "Max", dog2 = "Bailey", dog3 = "Harriet"; collection.add (dog1); collection.add (dog2); collection.add (dog3); // Оразмеряване System.out.println ("Създадена колекция" + ", размер =" + collection.size () + ", isEmpty =" + collection.isEmpty ()); // Containment System.out.println ("Колекцията съдържа" + dog3 + ":" + collection.contains (dog3)); // Повторение. Iterator поддържа hasNext, след това премахнете System.out.println ("Итерация на колекция (несортирано):"); Итератор итератор = collection.iterator (); докато (итератор.hasNext ()) System.out.println ("" + iterator.next ()); // Премахване на collection.remove (dog1); collection.clear (); }}

Let's now build on our basic knowledge of collections and look at other interfaces and implementations in the Java Collections Framework.

Good concrete implementations

We have exercised the Collection interface on a concrete collection, the HashSet. Let's now look at the complete set of concrete collection implementations provided in the Java Collections framework. (See the Resources section for a link to Sun's annotated outline of the Java Collections framework.)

Implementations
Hash Table Resizable Array Balanced Tree (Sorted) Linked List Legacy
Interfaces Set HashSet * TreeSet * *
List * ArrayList * LinkedList Vector
Map HashMap * TreeMap * Hashtable

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.

Последният основен интерфейс в Java Collections Framework е Map. Този интерфейс е реализиран с две нови конкретни реализации, TreeMapи HashMap. Това TreeMapе балансирано изпълнение на дърво, което сортира елементи по ключа.

Нека илюстрираме използването на Mapинтерфейса с прост пример, който показва как да добавяте, заявявате и изчиствате колекция. Този пример, който използва HashMapкласа, не се различава много от начина, по който използвахме Hashtableпреди дебюта на рамката Collections. Сега, с актуализацията на, за Hashtableда поддържа Mapинтерфейса, можете да замените реда, който създава екземпляра на, HashMapи да го замените с инстанция на Hashtable.