Wat is die voordele van die Iterator-koppelvlak in Java?
-
01-07-2019 - |
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:
Hierdie koppelvlak is 'n lid van die Java-versamelings Raamwerk.
- Iterators laat die oproeper toe om te verwyder elemente uit die onderliggende versameling tydens die iterasie met goed gedefinieerde semantiek.
- Metode name verbeter is.
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.
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 'nIterator
uit. Hierdie uitsondering kan jy weet dat dieIterator
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:
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 'n> 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.