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



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

Резюме


Да прегледаме колекциите доставяни със стандартната Java (1.0 и 1.1) библио­те­ка (BitSet не е включена тук понеже е клас за по-специална употреба):

  1. Масивът асоциира числени индекси с обектите. Той съдържа обекти от известен тип, така че не е необходимо да се прави каст. Може да бъде мно­го­размерен и може да съдържа примитиви. Обаче дължината му не може да бъ­де променяна след като е създаден.

  2. Vector също асоциира числени индекси с обекти – маое да мислите за масивите и Vectors като колекции с произволен достъп. Vector ав­то­ма­ти­че­ски си променя дължината с въвеждането на нови елементи. Но ArrayList мо­же да съдържа само манипулатори на Object, така че не може да съ­дър­жа примитиви и трябва да се прави кастинг когато се извлича Object ма­ни­пу­латор от колекцията.

  3. Hashtable е тип Dictionary, което е начин да се асоциират не числа, но обекти с други обекти. Hashtable също поддържа произволен достъп до обектите, фактически цялата работа в тях е фокусирана върху бързия достъп.

  4. Stack е "проследен влязъл-първи излиза" (LIFO) опашка.

Ако сте запознати със структурите данни, може да се чудите защо няма по-бо­га­то множество колекции. От функционална гледна точка нуждаете ли се от повече колекции? С Hashtable може да вмъквате неща и да ги намирате бързо, а с Enumeration може да се движите през колекцията и да извършвате операция над всеки елемент от последователността. Това е мощен инструмент и може би той би трябвало да е достатъчен.

Но Hashtable няма концепция за подреждане. Vectors дават линейно на­реж­да­не, но е скъпо да се вмъкне елемент в средата на всеки от тях. В добавка опаш­ки­те, дековете, опашките с приоритет и дърветата са за подреждане на еле­мен­ти­те, не само за слагане и последващо намиране на елементи линейно. Тези струк­тури данни са също полезни, затова са включени в Standard C++. Поради та­зи причина ще считате колекциите в стандартната Java библиотека само като на­чална точка и, ако трябва да използвате Java 1.0 или 1.1, използвайте JGL ко­га­то се нуждаете от нещо извън това.



Ако може да използвате Java 2 ще използвате само Колекциите на Java 2, които ве­роятно ще удовлетворят всичките ви нужди. Забележете че повечето от тази кни­га беше създадена чрез Java 1.1, така че ще видите, че колекциите които са из­ползвани до края на книгата са тези от Java 1.1: Vector и Hashtable. Това е мал­ко болезнено ограничение на моменти, но дава по-добра обратна съв­ме­сти­мост със стар Java код. Ако пишете нов код с Java 2, Колекциите на Java 2 ще ви слу­жат много по-добре.

Упражнения


  1. Създайте нов клас наречен Gerbil с int gerbilNumber който се инициализира в конструктра (подобно на Mouse примера в тази глава). Дайте му метод на­ре­чен hop( ) който извежда кое gerbil число е и че то подскача. Създайте ArrayList и добавете много Gerbil обекти във Vector. Сега използвайте ме­то­да elementAt( ) за придвижване през Vector и извикайте hop( ) за всеки Gerbil.

  2. Променете упражнение 1 така че да използва Iterator за придвижване през Vector докато се вика hop( ).

  3. В AssocArray.java сменете примера така че да използва Hashtable вместо AssocArray.

  4. Вземете класа Gerbil от упражнение 1 и го сложете в Hashtable, асоциирайки името на Gerbil като String (ключа) за всеки Gerbil (стойността) които сла­га­те в таблицата. Вземете Iterator за keys( ) и го използвайте за придвиж­ва­не през Hashtable, оглеждайки Gerbil за всеки ключ и печатайки клю­ча, каз­вай­ки на gerbil да направи hop( ).

  5. Променете упражнение 1 в глава 7 да използва ArrayList за съдържане на Rodentи и Iterator за придвижване през последователността от Rodentи. Пом­нете че ArrayList съдържа само Objects така че трябва да се прави каст (т.е.: RTTI) когато се прави достъп до отделни Rodentи.

  6. (Преходно) В глава 7 намелете примера GreenhouseControls.java, който се съ­стои от три файла. В Controller.java класът EventSet е точно колекция. Про­менете кода да използва Stack вместо EventSet. Това ще изисква повече от само заместването на EventSet със Stack; ще трябва да използвате също и Iterator ца циклене в множеството елементи. Вероятно ще намерите че е по-лес­но да третирате на моменти колекцията като Stack и в други моменти ка­то Vector.

  7. (Предизвикателство). Намерете сорса на Vector в библиотеката сорс на Java коя­то идва с всички Java дистрибуции. Копирайте този код и направете спе­ци­ална версия наречена intVector която съдържа само int. Проучете какво ще трябва за да се направи специална версия на Vector за всички примитивни ти­пове. Сега проучете какво ще стане ако създадете клас-свързан списък кой­то работи с всички примитивни типове. Ако някога се реализират па­ра­ме­три­зираните типове в Java, те ще дадат начин да се свърши тази работа ав­то­ма­тично за вас (както и много други ползи).

9: Обработка на грешки чрез изключения


Основната философия на Java е че “лошо формиран код няма да бъде задействан.”

Както и със C++, идеалния момент да се хване грешка е времето на ком­пи­ла­ция, преди даже да се опитате да пуснете програмата. Обаче не всички грешки мо­гат да бъдат открити по време на компилация. Определена част проблеми мо­гат да се обработват само по време на изпълнение, по някакъв формализъм, къ­дето източникът на грешката трябва да има начин да подаде информация на ко­да, който ще я обработва, за да може обработката да бъде подходяща.

В C и други ранни езици можеше да съществуват няколко такива формализма, а освен това те бяха задавани като конвенция, а не като част от програмния език. Типично се връщаше стойност и се слагаше флаг, като се предполагаше, че по­лу­чателят ще провери флага и ще изследва стойността за да разбере про­бле­ма. Обаче с течение на годините стана ясно, че програмистите които правят би­блио­теките имат тенденция да се считат за непобедими, както в: “Да, грешки мо­­гат да се появят при другите но не и в моя код.” Така, не много изненадващо, те не правеха нужните проверки (а и понякога ситуациите на грешка бяха твър­де тъпи за да се проверява за тях1). Ако бяхте достатъчно последователни да про­верявате за грешки всеки път като извикате метод, вашият код рискуваше да се превърне в нечитаем кошмар. Понеже програмистите трябваше да се се опра­вят с тези програмни системи те упорито поддържаха че: Този подход към обра­ботката на грешки е главното ограничение пред правенето на добри, го­ле­ми, управляеми програми.

Решението е да се разкара решаването на въпросите според случая от обра­бот­ка­та на грешки и да се въведе формализъм. Това фактически има дълга история, по­неже реализации на поддръжка на изключения се отнасят и за операционни си­стеми от 1960-те години и даже за on error goto на BASIC. Но поддръжката на изключения в C++ беше базирана на тази в Ada, а в Java е основана пре­дим­но на C++ (макар и повече да изглежда на Object Pascal).

Думата “exception” се има пред вид в значението “Вземам изключение за нещо.” В точката на възникване на проблема би могло да не се знае какво да се пра­ви с него, но се знае, че не може просто весело да се продължи; трябва да се спре и някой, някъде, трябва да изясни какво ще се прави. Но вие нямате ин­фор­мация в текущия момент за решаване на проблема. Така че представяте про­блема в по-висок контекст така че някой с нужната информация ще вземе мер­ките (доста подобно на веригата от команди (при командването на нещо, на­пример кораб-бел.пр.)).

Другата голяма полза от поддържането на изключенията е че те очистват кода. Наместо да се проверява за конкретна грешка и това да се прави в няколко ме­ста в програмата, повече няма да се проверява в точката на извикване на ме­то­да (понеже изключението гарантира, че някой ще го хване). Необходимо е да се обра­боти проблема само в едно място, тъй наречения exception handler. Това спе­стява писане и разделя кода за нещата които трябва да се правят от този кой­то е за в случай че се развали нещо. Изобщо да се пише, чете и тества код ста­ва много по-ясно като се използват изключения, отколкото по стария начин.

Понеже поддръжката на изключения се налага от компилатора на Java, има тол­ко­ва много примери в тази книга които могат да се напишат без знание на по­дроб­ности. Тази глава ви въвежда в нещата, които позволяват да напишете код за правилна обработка на изключенията, а също и как да генерирате свои соб­стве­ни изключения, ако ваш метод има неприятности.




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




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

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