Книга е още в много ранна фаза на написване



страница49/73
Дата25.07.2016
Размер13.53 Mb.
#6732
1   ...   45   46   47   48   49   50   51   52   ...   73

Колекциите на Java 2


За мен колекциите са един от най-мощните инструменти за програмиране. Мо­же да сте забелязали, че съм малко разочарован от колекциите на Java до вер­сия 1.1. Като резултат огромно удоволствие бе да видя, че в Java 2 на ко­лек­ции­те бе обърнато необходимото внимание, те бяха цялостно преработени (от Joshua Bloch от Sun). Считам че колекциите на Java 2 са едната главна черта на вер­сията (другата е Swing библиотеката, разгледана в глава 13) понеже те значи­телно увеличават програмистките мускули и извеждат Java на една линия с по-утвърдени програмни системи.

Част от преработката прави нещата по-свързани и смислени. Например вного име­на са по-къси, по-изразителни, по-лесни за разбиране и четене, както и за пи­сане. Някои имена са променени за съгласуване с приетата терминология: мой любим пример е “iterator”вместо “enumeration.”

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

Проектирането на библиотека колекции е трудно (както повечето проблеми свър­зани с библиотеки). В C++ STL се основава на много различни класове. То­ва е по-добре от наличното преди STL (нищо), но не се вписваше добре в Java. Ре­зултатът беше малко смущаващо блато от класове. В другата крайност аз съм виж­дал библиотека, състояща се от един клас, “collection,” който работи като ArrayList и HashMap едновременно. Проектантите на колекциите в би­блио­те­ка­та на Java 2 искаха да постигнат баланс: пълната функционалност, която се ис­ка от редовна библиотека, но по-голяма леснота за използване отколкото STL и други подобни библиотаки. Резултатът може да изглежда малко недобър на ме­ста. За разлика от решенията приети в ранните Java тези неуспехи не са не­щаст­ни случаи, а внимателно подбрани компромиси с цената на ефективността. Мо­же да отнеме повече време да свикнете с някои аспекти на библиотеките, но мис­ля че бързо ще приемете и започнете да използвате тези нови инструменти.

Колекциите на Java 2 библиотеката вземат въпроса за “владеене на вашите обек­ти” и го разделят между две различни концепции:


  1. Collection: група от отделни елементи, често с прилагане на някакво пра­вило към тях. List трябва да държи елементите на конкретна по­сле­до­ва­тел­ност, а Set не може да има дублиращи се елементи. (Bag, което не е реа­ли­зи­рано в Collections библиотеката на Java 2 поради това, че Listовете дават та­зи функционалност, няма такива правила.)

  2. Map: група от двойки ключ-стойност (каквито сте виждали досега като Hashtable). На пръв поглед това трябва да бъдат Collectionи от двойки, но ко­гато се опитате да го реализирате по този начин става тромаво, така че е по-добре да бъде отделна концепция. От друга страна, удобно е да се пре­глеж­дат части от Map чрез създаване на Collection да представя съот­вет­на­та порция. Така Map може да връща Set от своите ключове, List от своите стой­ности или List от своите двойки. Mapовете, както масивите, могат лес­но да бъдат разширени до нови стойности без необходимост от нови кон­цеп­ции: просто правите Map чиито стойности са Mapове (и стойностите на тези Mapове могат да бъдат Mapове и т.н.).

Collectionите и Mapовете могат да бъда прилагани по много различни начини, съответно на програмистките нужди. Полезно е да се погледне диаграмата на колекциите на Java 2:




Тази диаграма може да изглежда замайващо сложна на пръв поглед, но до края ня главата ще видите, че има само три класа колекции: Map, List и Set и само две или три реализации на всяка една (с, типично, предпочитана версия). Ко­га­то това стане колекциите на Java 2 не би трявало да изглеждат толкова за­пла­ши­тел­но.

Кутийките с прекъсната линия представляват interfaceите, с линия от точки — abstract класовете, а с непрекъсната линия са нормалните (конкретни) класове. Стрел­ките с прекъсната линия показват че даден клас прилага даден interface (или в случая на abstract клас, частично прилага този interface). Стрелките с двой­на линия показват, че може да се правят обекти от сочения клас. Например вся­ка Collection може да прави Iterator, докато List може да прави ListIterator (как­то и обикновен Iterator, тъй като List е наследен от Collection).

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

List x = new LinkedList();

Разбира се, бихте могли да решите да направите x LinkedList (вместо родов List) и да дадете точна информация за типа на x. Красотата (и целта) на из­полз­ва­нето на interface е че ако решите да промените реализацията, всичко което ще е необходимо е да смените типа в точката на създаването, както тук:

List x = new ArrayList();

Останалата част от кода може да остане незасегната.

В йерархията на класовете може да се видят множество класове, чиято декла­ра­ция започва с “Abstract,” а това може да е смущаващо отначало. Те са просто ин­струменти, които частично прилагат даден интерфейс. Ако правехте ваш соб­ствен Set, например, не бихте започнали с интерфейса на Set и реализация на всички методи, вместо това бихте наследили от AbstractSet и сторили ми­ни­мал­но необходимото за създаване на новия клас. Обаче Колекциите в би­блио­те­ката на Java 2 съдържат достатъчно функционалност за удовлетворяване на нуж­дите ви практически за всичко. Така че за вашите цели бихте могли да игно­ри­рате всичко, което започва с “Abstract.”

Поради това, както гледате диаграмата, ви засягат само онези interfaceи от гор­на­та част на диаграмата и конкретните класове (онези с непрекъсната линия). Ти­пично ще правите обекти от конкретни класове, ъпкаст към съответния interface, а после ще използвате interface-а в останалата част от вашия код. Ето прост пример, който попълва Collection със String обекти и после извежда все­ки обект от тази Collection:

//: c08:newcollections:SimpleCollection.java

// A simple example using Java 2 Collections

package c08.newcollections;

import java.util.*;


public class SimpleCollection {

public static void main(String[] args) {

Collection c = new ArrayList();

// Upcast because we just want to

// work with Collection features
for(int i = 0; i < 10; i++)

c.add(Integer.toString(i));

Iterator it = c.iterator();

while(it.hasNext())

System.out.println(it.next());

}

} ///:~



Всичките примери за Java 2 Collections библиотеките ще трябва да се сложат в под­директория newcollections, така че да се напомни че ще работят само с Java 2. Като резултат може да стартирате програмата така:

java c08.newcollections.SimpleCollection

с подобен синтаксис за другите програми от главата.

Може да се види че Java 2 Collections са част от java.util библиотеката, така че ня­ма нужда от никакви допълнителни import оператори за използването им.

Първата линия в main( ) създава ArrayList и после го превръща към Collection. Тъй като този пример използва само методите на Collection всеки обект на­сле­ден от Collection би работил, но ArrayList е типичният работен кон на Collection и заема мястото на Vector.

Методът add( ) , както показва името му, добавя нов елемент към Collection. Оба­че документацията грижливо твърди че add( ) “осигурява че тази Collection съ­държа посочения елемент.” Това е за да се позволи в смисъла на Set, който до­бавя елемент само ако още няма такъв добавен. С ArrayList, или който и да е сорт List, add( ) винаги значи “пъхни го вътре.”



Всички Collectionи могат да дадат Iterator чрез техния iterator( ) метод. Iterator е точно като Enumeration, който замества, освен че:

  1. Използва име (iterator) което е исторически признато и прието в ООП общността.

  2. Използва по-къси имена на методи от Enumeration: hasNext( ) вместо hasMoreElements( ), next( ) вместо nextElement( ).

  3. Въвежда нов метод, remove( ), който маха последния елемент даден от Iterator. Така че може да извикате remove( ) само веднъж сле всяко извикване на next( ).

В SimpleCollection.java може да видите че Iterator е създаден и използван за работа с Collection, извеждайки всеки елемент.



Сподели с приятели:
1   ...   45   46   47   48   49   50   51   52   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница