Cinci lucruri despre care nu știai

API-ul colecțiilor Java de către mulți dezvoltatori Java a fost perceput ca o înlocuire foarte necesară a rețelelor standard, eliminându-le neajunsurile. Asocierea colecțiilor în primul rând cu ArrayList nu este o mare greșeală, dar cei care caută pot descoperi mult mai mult în colecții.







Despre această serie de articole

Credeți că știți cum să programați în Java? De fapt, majoritatea dezvoltatorilor sunt familiarizați doar superficial cu platforma Java, învățând doar ceea ce este necesar pentru a face munca. În această serie de articole, Ted Newward intră în funcționalitatea de bază a platformei Java pentru a vorbi despre fapte puțin cunoscute despre faptul că cunoștințele pot ajuta cu cele mai complexe sarcini de programare.

În mod similar, deși Map (și implementarea comună a lui HashMap) reprezintă o modalitate excelentă de a crea perechi de nume-valoare sau valori-cheie, nu există niciun motiv să vă limitați la aceste instrumente familiare. Puteți remedia o mulțime de coduri potențial defecte prin selectarea API-ului potrivit sau chiar a colecției corecte.

1. Colecțiile împrăștie mese

De exemplu, pentru a forma un șir din conținutul unei matrice, trebuie să ocolim întreaga matrice și să îmbinăm conținutul tuturor elementelor sale într-un obiect String. întrucât în ​​colecții există o implementare gata a metodei toString ().

Cu câteva excepții, se recomandă ca fiecare matrice care ajunge la dvs. să fie convertită într-o colecție cât mai curând posibil. Aceasta conduce la întrebarea: cât de ușor este să efectuați o astfel de transformare? Se pare că Java API de colectare face această sarcină foarte simplă, după cum se arată în Lista 1:

Listing 1. ArrayToList

Rețineți că colecția de liste returnată este imuabilă, așadar încercarea de a adăuga elemente noi va arunca o UnsupportedOperationException.

Și, deoarece în metoda Arrays.asList (), parametrul varargs este folosit pentru a adăuga elementele List. cu aceasta, puteți crea cu ușurință o colecție de liste de obiecte nou create.

2. Iterația este ineficientă

Este adesea necesar să mutați conținutul unei colecții (mai ales una care a fost creată dintr-o matrice) într-o altă colecție sau să ștergeți unele dintre obiectele din colecție.

Soluția naturală aici este de a ocoli (folosind iteratorul) colecția și de a adăuga sau elimina elementele necesare. Cu toate acestea, nu ar trebui să faceți acest lucru.

Iterația în acest caz are câteva dezavantaje serioase:

  • este ineficient să se modifice dimensiunea colecției de fiecare dată când adăugați sau eliminați un element;
  • De fiecare dată când se recepționează o blocare, se efectuează o operație, iar blocarea este eliberată, pot apărea probleme asociate accesului concomitent;
  • Puteți să experimentați situații de curse când accesați o colecție din alte fire în timp ce adăugați sau eliminați articole.

Toate aceste probleme pot fi evitate folosind metodele addAll sau removeAll. transferând către ele colecții care conțin elemente care trebuie adăugate sau șterse.

3. Bucla pentru orice obiect cu interfața Iterable

Bucla extinsă este una dintre cele mai utile îmbunătățiri adăugate la Java 5, care au eliminat ultima barieră în lucrul cu colecțiile din Java.

Anterior, dezvoltatorii trebuiau să primească manual Iteratorul. apoi utilizați următoarea metodă () pentru a obține obiectul pe care îl îndreaptă acest Iterator și apoi verificați folosind metoda hasNext (). dacă există încă obiecte. Începând cu Java 5, în schimb, puteți folosi buclă for, în care toate acestea sunt tratate automat.







De fapt, acest ciclu poate fi folosit când lucrați cu orice obiect care implementează interfața Iterable. nu doar cu colecțiile.

Lista 2 prezintă o modalitate de a face copiii obiectului Persoană accesibilă ca iterator. În loc să transmită o trimitere la lista internă (care va permite apelantului din afara obiectului Persoană să îi adauge copiii - ceea ce majoritatea părinților nu ar dori), tipul Persoana implementează interfața Iterable. Această abordare permite, de asemenea, utilizarea bucla extinsă pentru a ocoli copiii unui obiect Persoană.

Lista 2. Extinsă pentru buclă: arătați-mi copiii

Utilizarea Iterable are unele dezavantaje evidente atunci când modela un domeniu, deoarece folosind metoda iterator (), puteți să mențineți o singură colecție de obiecte în acest fel. Cu toate acestea, pentru astfel de cazuri, în cazul în care colecția de copii în sine se sugerează, interfața Iterable face din programarea subiectului mult mai ușor și mai evident.

4. Algoritmi clasici și personalizați

Ați vrut vreodată să ocoliți colecția, dar nu în mod direct, dar în ordine inversă? Acesta este locul unde algoritmul de colectare Java poate fi util.

În listele 2, copiii obiectului Persoana sunt enumerați în ordinea în care au fost transmise, dar acum vrem să le enumerăm în ordine inversă. Ați putea scrie un altul pentru bucla și inserați obiectele în noua colecție ArrayList în ordine inversă, dar acest lucru poate fi obositor când utilizați acest cod pentru a treia sau a patra oară.

Aici puteți aplica un algoritm nefolosit rar folosit, prezentat în Lista 3.

Listing 3. ReverseIterator

În clasa Colecții există mai mulți astfel de "algoritmi" - metode statice care iau ca obiect obiectul Colecțiilor de clasă și efectuează acțiuni independente de implementarea acestei colecții.

În plus, algoritmii prezentați în colecțiile de clasă. cu siguranță nu ultimul cuvânt din arhitectura remarcabilă a acestui API. De exemplu, prefer ca metodele să nu modifice direct conținutul (colecția trimisă acestora). Pentru astfel de cazuri, este posibil să se scrie algoritmi personalizați, dintre care unul este prezentat în Lista 4.

Listing 4. Simplificați ReverseIterator

5. Extindeți API-ul de colectare

Algoritmul personalizat de mai sus ilustrează cea mai recentă caracteristică a API-ului de colectare Java: poate fi extins și modificat pentru a se potrivi nevoilor dezvoltatorilor.

De exemplu, să presupunem că dorim ca lista copiilor unui obiect Persoană să fie întotdeauna ordonată după vârstă. Puteți scrie un algoritm care va sorta lista de fiecare dată (de exemplu, folosind metoda Collections.sort), dar ar fi mult mai bine dacă clasa de colectare a făcut această sortare în sine.

De fapt, poate nu vă pasă de ordinea în care obiectele au fost inserate în colecție (ceea ce este de o importanță fundamentală pentru colecția de liste). Poate doriți doar să le păstrați în ordinea sortimentului.

Nici o colecție din pachetul java.util nu îndeplinește aceste cerințe, dar este destul de ușor să scrii singură clasa necesară. Tot ce aveți nevoie este să creați o interfață care să descrie comportamentul abstract pe care colecția ar trebui să îl furnizeze. De exemplu, interfața este SortedCollection. care are doar un scop comportamental (listare 5).

Listing 5. SortedCollection

Scrie implementarea acestei interfețe este foarte simplă (listare 6).

Listing 6. ArraySortedCollection

Această implementare a fost scrisă "pe genunchi", fără să se gândească la optimizare și, evident, merită un pic redeschis. Cu toate acestea, punctul este că API-ul de colectare Java nu este în niciun caz soluția finală pentru tot ceea ce se referă la colecții. Trebuie să se extindă și să-l încurajeze.

Desigur, unele extensii vor fi din categoria soluțiilor "de mare putere", de exemplu cele care au apărut în pachetul java.util.concurrent. Cu toate acestea, alte extensii pot fi destul de simple - de exemplu, scrierea unui algoritm personalizat sau extinderea unei clase de colecții existente.

Extinderea API-ului colecțiilor Java poate părea extraordinar de dificilă, însă, prin a începe să faceți acest lucru, veți descoperi că nu este atât de dificil cum credeați.

În concluzie

Ca API de serializare, API-ul de colectare Java este plin de complicații, așa că nu închidem acest subiect. În următorul articol din seria 5-lucruri, vom vorbi despre încă cinci modalități de a obține mai mult din API-ul de colectare Java.







Articole similare

Trimiteți-le prietenilor: