Vra

Ek het pas geleer hoe die Java Collections Framework datastrukture in gekoppelde lyste implementeer.Van wat ek verstaan, Iterators is 'n manier om deur die items in 'n datastruktuur soos 'n lys te blaai.Hoekom word hierdie koppelvlak gebruik?Hoekom is die metodes hasNext(), next() en remove() nie direk gekodeer na die datastruktuurimplementering self nie?

Van die Java-webwerf: skakel teks

openbare koppelvlak Iterator<E>

'N iterator oor 'n versameling.Iterator neem die plek in van Opsomming in die Java versamelings raamwerk.Iterators Verskil op twee maniere van opsommings:

  • Iterators laat die oproeper toe om te verwyder elemente uit die onderliggende versameling tydens die iterasie met goed gedefinieerde semantiek.
  • Metode name verbeter is.
Hierdie koppelvlak is 'n lid van die Java-versamelings Raamwerk.

Ek het probeer om rond te google en kon nie 'n definitiewe antwoord kry nie.Kan iemand lig werp oor hoekom Sun gekies het om dit te gebruik?Is dit as gevolg van beter ontwerp?Verhoogde sekuriteit?Goeie OO-oefening?

Enige hulp sal baie waardeer word.Dankie.

Was dit nuttig?

Oplossing

  

Hoekom is hierdie koppelvlak gebruik?

Omdat dit ondersteun die basiese operasies wat sou toelaat dat 'n kliënt programmeerder om Itereer oor enige soort versameling (let op: nie noodwendig 'n Collection in die Object sin).

  

Hoekom is die metodes ... nie direk   gekodeer om die data struktuur   implementering self?

Dit is, hulle is maar net Private gemerk sodat jy nie kan bereik in hulle en muck met hulle. Meer spesifiek:

  • Jy kan implementeer of oorerf n Iterator sodanig dat dit iets die standaard kinders nie doen nie, sonder om die werklike voorwerp dit iterate oor verander.
  • voorwerpe wat oor kan deurkruis nie nodig het om hul koppelvlakke gewy met traversal metodes, in die besonder 'n hoogs gespesialiseerde metodes.
  • Jy kan uitdeel Iterators om egter baie kliënte wat jy wil, en elke kliënt kan deurkruis in hul eie tyd, op hul eie spoed.
  • Java Iterators van die java.util pakket in die besonder sal 'n uitsondering te gooi as die stoor wat hulle rug is verander terwyl jy nog 'n Iterator uit. Hierdie uitsondering kan jy weet dat die Iterator nou kan terugkeer ongeldig voorwerpe.

Vir eenvoudige programme, geeneen van hierdie lyk waarskynlik die moeite werd. Die soort van kompleksiteit wat hulle nuttig maak sal vinnig kom op jou, al is.

Ander wenke

Jy vra: "Hoekom is die metodes hasNext () langs () en verwyder () nie direk gekodeer om die data struktuur implementering self?"

.

Die Java Collections raamwerk kies om die Iterator koppelvlak definieer as externalized om die versameling self. Gewoonlik, aangesien elke Java versameling implemente die Iterable koppelvlak, 'n Java program sal iterator bel om sy eie iterator skep sodat dit gebruik kan word in 'n lus. Soos ander het daarop gewys, Java 5 stel ons in staat om direkte gebruik van die iterator, met 'n vir-elke lus.

Externaliserend die iterator om sy versameling laat die kliënt om te bepaal hoe 'n iterate deur 'n versameling. Een gebruik geval dat ek kan dink waar dit nuttig is wanneer 'n mens 'n 'n ongeleide versameling soos al die webblaaie op die internet na die indeks.

In die klassieke GOF boek, die kontras tussen interne en eksterne iterators is uitgespel baie duidelik.

  

'n fundamentele kwessie is om te besluit watter party conrols die iterasie, die iterator of die kliënt wat die iterator gebruik. Wanneer die kliënt die iterasie beheer, is die iterator genoem 'n eksterne iterator, en wanneer die iterator beheer dit, die iterator is 'n interne iterator. Kliënte wat 'n eksterne iterator gebruik moet die traversal bevorder en vra die volgende element uitdruklik van die iterator. In teenstelling hiermee het die kliënt oorhandig 'n interne iterator 'n operasie uit te voer, en die iterator geld wat operasie aan elke element ....

     

Eksterne iterators is meer buigsaam as interne iterators. Dit is maklik om twee versamelings vir gelykheid te vergelyk met 'n eksterne iterator, byvoorbeeld, maar dit is feitlik onmoontlik om met interne iterators ... Maar aan die ander kant, interne iterators is makliker om te gebruik, omdat hulle die iterasie logika vir jou definieer.

Vir 'n voorbeeld van hoe interne iterators werk, sien Ruby se Enumerable API, wat interne iterasie metodes soos each het. In Ruby, die idee is om 'n blok van die kode (dit wil sê 'n sluiting) slaag om 'n interne iterator sodat 'n versameling kan sorg van sy eie iterasie.

Dit is belangrik om die versameling afgesien van die wyser te hou. die iterator wys na 'n spesifieke plek in 'n versameling, en dus nie 'n integrale deel van die versameling. So, vir 'n geval, jy kan 'n paar iterators gebruik oor dieselfde versameling.

Die nadeel van hierdie skeiding is dat die iterator is nie bewus van veranderinge aan die versameling dit iterate op. sodat jy kan nie verander die struktuur van die versameling en verwag dat die iterator om voort te gaan dit werk sonder "klagtes".

Gebruik die Iterator koppelvlak laat enige klas wat sy metodes implementeer toe om as iterators op te tree.Die idee van 'n koppelvlak in Java is om op 'n manier 'n kontraktuele verpligting te hê om sekere funksies in 'n klas te verskaf wat implements die koppelvlak, om op 'n manier op te tree wat deur die koppelvlak vereis word.Aangesien die kontraktuele verpligtinge nagekom moet word om 'n geldige klas te wees, sal ander klasse wat die klas sien implements die koppelvlak en dus gerusgestel om te weet dat die klas daardie sekere funksies sal hê.

In hierdie voorbeeld, eerder as om die metodes (hasNext(), next(), remove()) in die LinkedList klas self, die LinkedList klas sal verklaar dat dit implements die Iterator koppelvlak, sodat ander weet dat die LinkedList kan as 'n iterator gebruik word.Op sy beurt het die LinkedList klas sal die metodes van die implementeer Iterator koppelvlak (soos hasNext()), sodat dit soos 'n iterator kan funksioneer.

Met ander woorde, die implementering van 'n koppelvlak is 'n objekgeoriënteerde programmeringsopvatting om ander te laat weet dat 'n sekere klas het wat dit verg om te wees wat dit beweer om te wees.

Hierdie idee word afgedwing deur metodes te hê wat geïmplementeer moet word deur 'n klas wat die koppelvlak implementeer.Dit maak seker dat ander klasse wat die klas wil gebruik wat die Iterator koppelvlak wat dit inderdaad metodes sal hê wat Iterators moet hê, soos hasNext().

Daar moet ook op gelet word dat aangesien Java nie veelvuldige oorerwing het nie, die gebruik van koppelvlak gebruik kan word om daardie kenmerk na te boots.Deur verskeie koppelvlakke te implementeer, kan 'n mens 'n klas hê wat 'n subklas is om sekere kenmerke te erf, maar tog ook die kenmerke van 'n ander "erf" deur 'n koppelvlak te implementeer.Een voorbeeld sou wees, as ek 'n subklas van die wil hê LinkedList klas genoem ReversibleLinkedList wat in omgekeerde volgorde kan herhaal, kan ek 'n koppelvlak met die naam skep ReverseIterator en afdwing dat dit voorsiening maak vir a previous() metode.Sedert die LinkedList reeds implementeer Iterator, sou die nuwe omkeerbare lys beide die geïmplementeer het Iterator en ReverseIterator koppelvlakke.

Jy kan meer lees oor koppelvlakke van Wat is 'n koppelvlak? uit The Java Tutoriaal van Sun.

Verskeie gevalle van 'n interator kan gelyktydig gebruik word. Benader hulle as plaaslike wysers vir die onderliggende data.

BTW: ten gunste van koppelvlakke oor beton implementering verloor koppeling

Look vir die iterator ontwerp patroon, en hier: http://en.wikipedia.org/wiki / Iterator

Omdat jy kan iterating oor iets wat nie 'n datastruktuur. Kom ons sê ek het 'n netwerk aansoek wat resultate trek uit 'n bediener. Ek kan 'n Iterator wrapper rondom die resultate terugkeer en stroom hulle deur 'n standaard-kode wat 'n Iterator voorwerp aanvaar.

Dink aan dit as 'n belangrike deel van 'n goeie MVC ontwerp. Die data moet uit die Model (maw datastruktuur) een of ander manier kry om die vertoning. Met behulp van 'n Iterator as 'n tussenganger verseker dat die implementering van die model nooit blootgestel. Jy kan aanhou om 'n LinkedList in die geheue, inligting uit 'n dekripsie algoritme trek, of wikkel JDBC oproepe. Dit maak eenvoudig nie saak aan die oog, want die oog net besorg oor die Iterator koppelvlak.

'n Interessante papier bespreking van die voor- en nadele van die gebruik van iterators:

http://www.sei.cmu.edu /pacc/CBSE5/Sridhar-cbse5-final.pdf

Ek dink dit is net 'n goeie OO praktyk. Jy kan kode wat handel oor alle vorme van iterators het, en selfs gee jou die geleentheid om jou eie data strukture of net generiese klasse wat die iterator koppelvlak implementeer skep. Jy hoef nie te bekommer oor watter soort van implementering is agter dit.

Just M2C, as jy nie bewus was soos volg: jy kan direk vermy die gebruik van die iterator koppelvlak in situasies waar die vir-elke lus sal voldoende wees.

Uiteindelik, want Iterator vang 'n beheer onttrekking wat van toepassing is op 'n groot aantal van datastrukture is. As jy op jou kategorie teorie fu, kan jy jou gedagtes geblaas deur hierdie vraestel gebruik: die kern van die Iterator Patroon .

Wel dit lyk asof die eerste koeël punt maak voorsiening vir 'n multi-threaded (of enkele threaded as jy skroef) aansoeke om nie nodig het om die versameling sluit vir concurrency oortredings. In NET byvoorbeeld jy kan nie opsom en 'n versameling (of lys of enige IEnumerable) op dieselfde tyd te verander sonder sluit of erfgename van IEnumerable en oorheersende metodes (ons kry uitsonderings).

Iterator voeg net 'n algemene manier van gaan oor 'n versameling van items. Een van die mooi eienskappe is die i.remove () waarin jy die elemente van die lys wat jy iterating oor kan verwyder. As jy net probeer om items uit 'n lys te verwyder normaalweg sou dit vreemd gevolge hê of gooi en uitsondering nie.

Die koppelvlak is soos 'n kontrak vir alles wat dit implementeer. Jy is basies sê .. enigiets wat implemente 'n iterator is gewaarborg om hierdie metodes wat op dieselfde manier op te tree nie. Jy kan dit ook gebruik om iterator tipes om te slaag as dit is al wat jy omgee hantering in jou kode. (Jy kan nie omgee watter soort lys dit is .. jy net wil 'n Iterator slaag) Jy kan al hierdie metodes onafhanklik in die versamelings sit maar jy is nie die waarborg dat hulle optree dieselfde of dat hulle selfs dieselfde naam en handtekeninge.

Iterators is een van die vele ontwerp patrone beskikbaar in Java. Ontwerp patrone kan beskou word as handige boublokke, style, gebruik van jou kode / struktuur.

Vir meer inligting oor die Iterator ontwerp patroon lees check die hierdie webwerf wat praat oor Iterator sowel as baie ander ontwerpspatrone. Hier is 'n uittreksel uit die terrein op Iterator: http://www.patterndepot.com/ sit / 8 / Behavioral.html

  

Die Iterator is een van die eenvoudigste   en mees gebruikte van die ontwerp   patrone. Die Iterator patroon kan   jy beweeg deur middel van 'n lys of   versameling van data met behulp van 'n standaard   koppelvlak sonder om die ken   besonderhede van die interne   vertoë van daardie data. in   Daarbenewens kan jy ook 'n spesiale definieer   iterators dat 'n paar spesiale voer   verwerking en terugkeer net gespesifiseerde   elemente van die data-insameling.

Iterators kan gebruik word teen enige vorm van versameling. Hulle laat jou 'n algoritme teen 'n versameling van items, ongeag van die onderliggende implementering definieer. Dit beteken dat jy kan 'n lys, stel, String, lêer, Array, ens te verwerk.

Tien jaar van nou af jou lys implementering kan verander na 'n beter implementering en die algoritme sal steeds uitgevoer word moeiteloos daarteen.

Iterator is nuttig wanneer jy te doen het met versamelings in Java.

Vir-Elke lus (Java1.5) vir iterating oor 'n versameling of skikking of lys.

Die java.util.Iterator koppelvlak gebruik word in die Java Collections raamwerk om die wysiging van die versameling toelaat terwyl hy nog deur dit te herhaal. As jy net wil skoon Itereer oor 'n hele versameling, gebruik 'n vir-elke plaas, maar 'n onderstebo van Iterators is die funksies wat jy kry: 'n opsionele verwyder () operasie, en selfs beter vir die lys Iterator koppelvlak, wat bied voeg () en stel () bedrywighede te. Beide van hierdie interfaces toelaat om Itereer oor 'n versameling en om dit te verander struktureel terselfdertyd. Probeer om 'n versameling terwyl iterating deur dit met 'n vir-elke sou 'n ConcurrentModificationException gooi, gewoonlik omdat die versameling onverwags aangepas verander!

Neem 'n blik op die Array List klas

Dit het 2 privaat klasse daarin (innerlike klasse) genoem ITR en ListItr

Hulle implementeer onderskeidelik Iterator en die ListIterator koppelvlakke

openbare klas Array List ..... {// omringende klas

  private class Itr implements Iterator<E> {

        public E next() {
            return ArrayList.this.get(index++); //rough, not exact
        }

        //we have to use ArrayList.this.get() so the compiler will
        //know that we are referring to the methods in the 
        //enclosing ArrayList class

        public void remove() {
            ArrayList.this.remove(prevIndex);
        }

        //checks for...co mod of the list
        final void checkForComodification() {  //ListItr gets this method as well
             if (ArrayList.this.modCount != expectedModCount) { 
                 throw new ConcurrentModificationException();
             }
        }
  }

  private class ListItr extends Itr implements ListIterator<E> {
         //methods inherted....
        public void add(E e) {
            ArrayList.this.add(cursor, e);
        }

        public void set(E e) {
            ArrayList.this.set(cursor, e);
        }
  }

}

As jy 'n beroep die metodes iterator () en listIterator (), hulle terugkeer 'n nuwe geval van die private klas ITR of ListItr, en aangesien hierdie innerlike klasse is "binne" die omringende Array List klas, hulle kan vrylik die Array List verander sonder verwek 'n ConcurrentModificationException, tensy jy die lys terselfdertyd (conccurently) deur set te verander () byvoeg () of verwyder () metodes van die Array List klas.

scroll top