Programmēšana

Atkārtojot Java kolekcijas

Jebkurā laikā, kad jums ir lietu kolekcija, jums būs nepieciešams mehānisms, lai sistemātiski pārietu uz šīs kolekcijas priekšmetiem. Kā ikdienas piemēru ņemiet vērā televīzijas tālvadības pulti, kas ļauj mums atkārtoties, izmantojot dažādus televīzijas kanālus. Līdzīgi programmēšanas pasaulē mums ir nepieciešams mehānisms sistemātiskai iterācijai, izmantojot programmatūras objektu kolekciju. Java ietver dažādus iterācijas mehānismus, ieskaitot indekss (par masīva atkārtošanu), kursors (lai atkārtotu datu bāzes vaicājuma rezultātus), uzskaitījums (agrīnās Java versijās) un atkārtotājs (jaunākās Java versijās).

Iteratora modelis

An atkārtotājs ir mehānisms, kas ļauj secīgi piekļūt visiem kolekcijas elementiem, katram elementam veicot zināmu darbību. Būtībā iterators nodrošina līdzekli, lai "izveidotu cilpu" pār iekapsulētu objektu kolekciju. Iteratoru izmantošanas piemēri ietver

  • Apmeklējiet katru direktorijā esošo failu (aka mapi) un parādiet tās nosaukumu.
  • Apmeklējiet katru mezglu diagrammā un nosakiet, vai tas ir sasniedzams no noteiktā mezgla.
  • Apmeklējiet katru klientu rindā (piemēram, simulējot līniju bankā) un uzziniet, cik ilgi viņš vai viņa gaida.
  • Apmeklējiet katru mezglu kompilatora abstraktā sintakses kokā (kuru veido parsētājs) un veiciet semantisko pārbaudi vai kodu ģenerēšanu. (Šajā kontekstā jūs varētu izmantot arī Apmeklētāja modeli.)

Noteikti iteratoru izmantošanas principi: Kopumā jums vajadzētu būt iespējai vienlaikus veikt vairākus šķērsošanas gadījumus; tas ir, iteratoram vajadzētu pieļaut jēdzienu ligzdota cilpa. Atkārtotājam nevajadzētu būt nesagraujošam arī tādā nozīmē, ka iterācijas akts pats par sevi nedrīkst mainīt kolekciju. Protams, operācija, kas tiek veikta ar kolekcijas elementiem, iespējams, varētu mainīt dažus elementus. Var būt, ka atkārtotājs var arī atbalstīt elementa noņemšanu no kolekcijas vai jauna elementa ievietošanu noteiktā kolekcijas vietā, taču šādām izmaiņām jābūt skaidrām programmā, nevis iterācijas blakusproduktiem. Dažos gadījumos jums būs nepieciešami arī atkārtotāji ar dažādām šķērsošanas metodēm; piemēram, koka iepriekšēja un pēc pasūtījuma šķērsošana vai diagrammas šķērsošana vispirms ar dziļumu un platumu.

Atkārtotas sarežģītas datu struktūras

Es pirmo reizi iemācījos programmēt agrīnā FORTRAN versijā, kur vienīgā datu strukturēšanas iespēja bija masīvs. Es ātri uzzināju, kā atkārtot masīvu, izmantojot indeksu un DO cilpu. No turienes tas bija tikai īss garīgs lēciens idejai par kopēja indeksa izmantošanu vairākos masīvos, lai simulētu ierakstu masīvu. Lielākajai daļai programmēšanas valodu ir masīviem līdzīgas funkcijas, un tās atbalsta vienkāršu loku izveidošanu pāri masīviem. Bet mūsdienu programmēšanas valodas atbalsta arī sarežģītākas datu struktūras, piemēram, sarakstus, kopas, kartes un kokus, kur iespējas ir pieejamas, izmantojot publiskas metodes, bet iekšējās detaļas ir paslēptas klases privātajās daļās. Programmētājiem jāspēj šķērsot šo datu struktūru elementus, neatklājot to iekšējo struktūru, kas ir iteratoru mērķis.

Iteratori un četru bandu dizaina modeļi

Saskaņā ar Četru bandu (skatīt zemāk), Iteratora dizaina modelis ir uzvedības modelis, kura galvenā ideja ir "uzņemties atbildību par piekļuvi un šķērsošanu ārpus saraksta [ed. domāju kolekcija] objektu un ievietojiet to iteratora objektā. "Šis raksts attiecas ne tik daudz uz Iterator modeli, cik par iteratoru izmantošanu praksē. Lai pilnībā pārklātu modeli, būtu jāapspriež, kā iterators tiks veidots, dalībnieki ( objektus un klases) dizainā, iespējamos alternatīvos dizainos un dažādu dizaina alternatīvu kompromisos. Es drīzāk koncentrētos uz to, kā iteratori tiek izmantoti praksē, bet es jūs norādīšu uz dažiem resursiem, lai izpētītu Iterator modeli un dizaina modeļus parasti:

  • Dizaina modeļi: atkārtoti lietojamas objektorientētas programmatūras elementi (Addison-Wesley Professional, 1994), kuru autori ir Ērihs Gamma, Ričards Helms, Ralfs Džonsons un Džons Vlisīds (pazīstams arī kā Četru banda vai vienkārši GoF), ir galīgais resurss, lai uzzinātu par dizaina modeļiem. Lai arī grāmata pirmo reizi tika izdota 1994. gadā, tā joprojām ir klasika, par ko liecina fakts, ka ir bijuši vairāk nekā 40 izdrukas.
  • Merilendas Universitātes Baltimoras apgabala lektoram Bobam Tarram ir lielisks slaidu komplekts, kas paredzēts viņa kursam par dizaina modeļiem, ieskaitot ievadu Iterator modelī.
  • Deivida Gērija JavaWorld sērija Java dizaina modeļi iepazīstina ar daudziem modeļa Gang of Four dizaina modeļiem, ieskaitot Singleton, Observer un Composite modeļus. Arī vietnē JavaWorld Jeff Friesen jaunākajā trīsdaļīgajā dizaina modeļu pārskatā ir iekļauts GoF modeļu ceļvedis.

Aktīvie atkārtotāji vs pasīvie atkārtotāji

Atkārtotāja ieviešanai ir divas vispārīgas pieejas atkarībā no tā, kurš kontrolē atkārtojumu. Par aktīvs atkārtotājs (zināms arī kā precīzi izteikts atkārtotājs vai ārējais iterators), klients kontrolē iterāciju tādā nozīmē, ka klients izveido iteratoru, pasaka, kad pāriet uz nākamo elementu, pārbauda, ​​vai visi elementi ir apmeklēti utt. Šī pieeja ir izplatīta tādās valodās kā C ++, un tieši GoF grāmatā tai tiek pievērsta vislielākā uzmanība. Lai gan Java iteratoriem ir dažādas formas, aktīvā iteratora izmantošana būtībā bija vienīgā reālā iespēja pirms Java 8.

Priekš pasīvs iterators (pazīstams arī kā netiešs atkārtotājs, iekšējais iteratorsvai atzvanīšanas iterators), iterators pats kontrolē iterāciju. Klients būtībā iteratoram saka: "veiciet šo darbību ar kolekcijas elementiem". Šī pieeja ir izplatīta tādās valodās kā LISP, kas nodrošina anonīmas funkcijas vai slēgšanu. Līdz ar Java 8 izlaišanu šī iterācijas pieeja tagad ir saprātīga alternatīva Java programmētājiem.

Java 8 nosaukumu shēmas

Lai arī tas nav tik slikti kā Windows (NT, 2000, XP, VISTA, 7, 8, ...), Java versiju vēsturē ir iekļautas vairākas nosaukumu shēmas. Lai sāktu, vai Java standarta izdevums būtu jāatsaucas par "JDK", "J2SE" vai "Java SE"? Java versiju numuri sākās diezgan vienkārši - 1.0, 1.1 utt., Taču viss mainījās ar versiju 1.5, kuras nosaukums bija Java (vai JDK) 5. Atsaucoties uz agrīnām Java versijām, es izmantoju tādas frāzes kā "Java 1.0" vai "Java" 1.1, "bet pēc Java piektās versijas es izmantoju tādas frāzes kā" Java 5 "vai" Java 8. "

Lai ilustrētu dažādas iterācijas pieejas Java, man ir nepieciešams kolekcijas piemērs un kaut kas, kas jādara ar tā elementiem. Šī raksta sākotnējā daļā es izmantošu virkņu kolekciju, kas apzīmē lietu nosaukumus. Katram nosaukumam kolekcijā tā vērtību vienkārši izdrukāšu standarta izvadā. Šīs pamatidejas ir viegli attiecināmas arī uz sarežģītāku objektu kolekcijām (piemēram, darbiniekiem) un kur katra objekta apstrāde ir nedaudz vairāk iesaistīta (piemēram, katram augsti novērtētam darbiniekam tiek piešķirts 4,5 procentu paaugstinājums).

Citi iterācijas veidi Java 8

Es koncentrējos uz kolekciju atkārtošanu, taču Java ir arī citi, specializētāki iterācijas veidi. Piemēram, jūs varat izmantot JDBC ResultSet atkārtot rindas, kas atgriezušās no SELECT vaicājuma relāciju datu bāzē, vai izmantot a Skeneris atkārtot ievades avotu.

Atkārtojums ar uzskaites klasi

Java 1.0 un 1.1 versijās divas primārās kolekcijas klases bija Vector un Hashtable, un Iterator dizaina modelis tika ieviests klasē ar nosaukumu Uzskaitīšana. Retrospektīvi tas bija klases slikts nosaukums. Nejauciet klasi Uzskaitīšana ar jēdzienu enum veidi, kas neparādījās līdz Java 5. Šodien gan Vector un Hashtable ir vispārīgas klases, bet toreiz vispārējās nebija Java valodas daļa. Kods virkņu vektora apstrādei, izmantojot Uzskaitīšana izskatītos apmēram kā 1. saraksts.

Uzskaitīšana 1. Izmantojot virkni, lai atkārtotu virkņu vektoru

 Vektoru nosaukumi = new Vector (); // ... pievienot dažus nosaukumus kolekcijai Uzskaitījums e = nosaukumi.elementi (); while (e.hasMoreElements ()) {String name = (String) e.nextElement (); System.out.println (nosaukums); } 

Iterācija ar Iterator klasi

Java 1.2 iepazīstināja ar kolekciju klasēm, kuras mēs visi zinām un mīlam, un Iterator dizaina modelis tika ieviests atbilstoši nosauktajā klasē Iterators. Tā kā mums vēl nebija vispārīgu programmu Java 1.2, objekta liešana, kas atgriezts no Iterators joprojām bija vajadzīgs. Java versijām 1.2 līdz 1.4 virkņu saraksta atkārtošana var atgādināt 2. sarakstu.

Saraksts 2. Iteratora izmantošana, lai atkārtotu virkņu sarakstu

 Sarakstu nosaukumi = new LinkedList (); // ... pievienojiet dažus nosaukumus kolekcijai Iterator i = names.iterator (); while (i.hasNext ()) {String name = (String) i.next (); System.out.println (nosaukums); } 

Atkārtojums ar vispārīgajiem un uzlaboto for-loop

Java 5 deva mums interfeisu vispārīgus Atkārtojamsun uzlabotā for-loop. Uzlabotais for-loop ir viens no maniem visu laiku iecienītākajiem mazajiem Java papildinājumiem. Izveidot iteratoru un aicina to hasNext () un Nākamais() metodes kodā nav skaidri izteiktas, taču tās joprojām notiek aiz ainas. Tādējādi, kaut arī kods ir kompaktāks, mēs joprojām izmantojam aktīvo iteratoru. Izmantojot Java 5, mūsu piemērs varētu izskatīties kaut kas līdzīgs tam, ko redzat 3. sarakstā.

Saraksts 3. Izmantojot virknes un uzlaboto for-loop, atkārtojiet virkņu sarakstu

 Sarakstu nosaukumi = new LinkedList (); // ... pievienojiet dažus nosaukumus kolekcijai (String name: names) System.out.println (name); 

Java 7 deva mums dimanta operatoru, kas samazina ģenērisko līdzekļu daudzveidību. Ir pagājuši laiki, kad pēc atsaukšanās jāatkārto veids, kas izmantots, lai parādītu sugas klasi jauns operators! Java 7 mēs varētu vienkāršot 3. saraksta pirmo rindu šādi:

 Sarakstu nosaukumi = new LinkedList (); 

Viegla ņirgāšanās par vispārējiem

Programmēšanas valodas dizains ietver kompromisus starp valodas iezīmju priekšrocībām un sarežģītību, ko tās uzliek valodas sintaksei un semantikai. Attiecībā uz vispārējiem medikamentiem es neesmu pārliecināts, ka ieguvumi atsver sarežģītību. Generics atrisināja problēmu, kuras man nebija ar Java. Es parasti piekrītu Kena Arnolda viedoklim, kad viņš apgalvo: "Ģenerārie preparāti ir kļūda. Tā nav problēma, kas balstīta uz tehniskām nesaskaņām. Tā ir būtiska valodas dizaina problēma [...] Java sarežģītība ir papildināta ar to, kas man šķiet salīdzinoši neliels ieguvums. "

Par laimi, kaut arī vispārīgo klašu izstrāde un ieviešana dažreiz var būt pārāk sarežģīta, es atklāju, ka vispārīgo klašu izmantošana praksē parasti ir vienkārša.

Atkārtojums ar metodi forEach ()

Pirms iedziļināties Java 8 atkārtojuma funkcijās, pārdomāsim, kas ir nepareizs ar kodu, kas parādīts iepriekšējos sarakstos, kas nav nekas īsts. Pašlaik izvietotajās lietojumprogrammās ir miljoniem Java koda rindiņu, kurās tiek izmantoti aktīvi iteratori, kas līdzīgi tiem, kas parādīti manos sarakstos. Java 8 vienkārši nodrošina papildu iespējas un jaunus iterācijas veikšanas veidus. Dažiem scenārijiem jaunie veidi var būt labāki.

Java 8 galvenās jaunās funkcijas koncentrējas uz lambda izteiksmēm, kā arī ar tām saistītām funkcijām, piemēram, straumēm, metožu atsaucēm un funkcionālajām saskarnēm. Šīs jaunās Java 8 funkcijas ļauj mums nopietni apsvērt iespēju izmantot pasīvos atkārtotājus, nevis tradicionālākos aktīvos atkārtotājus. Jo īpaši Atkārtojams interfeiss nodrošina pasīvu iteratoru noklusējuma metodes veidā, ko sauc katram().

A noklusējuma metode, vēl viena jauna Java 8 iezīme ir metode saskarnē ar noklusējuma ieviešanu. Šajā gadījumā katram() metode tiek faktiski ieviesta, izmantojot aktīvo iteratoru, līdzīgi tam, ko redzējāt 3. sarakstā.

Kolekcijas klases, kuras īsteno Atkārtojams (piemēram, visām saraksta un kopas klasēm) tagad ir a katram() metodi. Šī metode prasa vienu parametru, kas ir funkcionāls interfeiss. Tāpēc faktiskais parametrs, kas nodots katram() metode ir kandidāts uz lambda izteiksmi. Izmantojot Java 8 funkcijas, mūsu darbības piemērs tiktu pārveidots formā, kas parādīta 4. sarakstā.

4. Iterācija Java 8, izmantojot forEach () metodi

 Sarakstu nosaukumi = new LinkedList (); // ... pievienojiet dažus nosaukumus kolekcijas nosaukumiem.forEach (nosaukums -> System.out.println (nosaukums)); 

Ievērojiet atšķirību starp pasīvo iteratoru 4. sarakstā un aktīvo iteratoru iepriekšējos trīs sarakstos. Pirmajos trijos sarakstos cilpas struktūra kontrolē iterāciju, un katras šķērsošanas laikā objekts tiek izgūts no saraksta un pēc tam tiek izdrukāts. 4. sarakstā nav skaidras cilpas. Mēs vienkārši sakām katram() metodi, ko darīt ar saraksta objektiem - šajā gadījumā mēs vienkārši izdrukājam objektu. Iterācijas kontrole atrodas katram() metodi.

Atkārtojums ar Java straumēm

Tagad apsvērsim iespēju darīt kaut ko nedaudz vairāk iesaistītu, nekā vienkārši izdrukāt nosaukumus mūsu sarakstā. Pieņemsim, ka, piemēram, mēs vēlamies saskaitīt to vārdu skaitu, kas sākas ar burtu A. Mēs varētu ieviest sarežģītāku loģiku kā daļu no lambda izteiksmes vai arī mēs varētu izmantot Java 8 jauno Stream API. Pieņemsim pēdējo pieeju.

$config[zx-auto] not found$config[zx-overlay] not found