2012-03-14 18 views
5

In ResultSet interfaccia v'è next metodo che tornare booleano e poi si può accedere direttamente al record corrente get metodiIterator metodo successivo

Perché Iterator da java.util proprio non cadere hasNext() metodo e hanno solo next metodo che si sposta il cursore sull'elemento successivo e restituire boolean?

+0

Ho provato qualcosa di simile mentre ((o = itr.next())! = Null), ho ottenuto NoSuchElementException. Se vedi l'implementazione del metodo nexter iterator in varie classi, vedrai NoSuchELementException lanciata controllando condizioni diverse. Per esempio, Abstractlist ha un bel blocco catch di IndexOutOfBoundsException per lanciare NoSuchElementException e nella classe LinkedBlockingDeque che abbiamo next! = Null check – Delta

risposta

8

Perché next() attualmente restituisce l'elemento successivo.

Java poteva hanno attuato il modello iteratore nello stesso modo in cui .NET fa, con un MoveNext() che restituisce un valore booleano, e quindi una proprietà Current con il valore "corrente" - ma è ancora due membri ...

L'altra alternativa ha un valore di ritorno che incapsula le due idee di "c'è un valore" e "qual è il valore se ce n'è uno" - una sorta di tipo Maybe, davvero. Naturalmente in Java, che significa che attribuisce un nuovo oggetto su ogni iterazione, che non è ideale ...

0

Procedimento ResultSetnext() è come hasNext() di iteratore. La maggior parte degli altri metodi di ResultSet invece del singolo metodo next() di Iterator.

Vorrei fare un'altra domanda: perché non hanno implementato l'iteratore ResultSet o almeno iterabile con i generici? Penso che la risposta sia che ResultSet appare in java prima di Iterator. Poco dopo sono stati introdotti molti strumenti tipo ORM, quindi la maggior parte delle persone semplicemente non usa JDBC direttamente e non si occupa di ResultSet.

Ma io non sono storico di JDK, quindi è la mia ipotesi.

+0

Inoltre, Iterable.next restituisce un singolo valore, mentre dopo aver fatto un ResultSet.next puoi fare molti getXXX per recuperare molti valori. Suppongo che ResultSet potrebbe essere stato implementato come un Iterator che restituisce un oggetto "Record" e quindi estrarre i campi dal Record. Suppongo che sarebbe stato più coerente. – Jay

+1

È vero che ResultSet era in Java prima di Iterator, ma Java ha avuto Enumeration dalla versione 1.0, che è il predecessore di Iterator e avrebbe potuto essere utilizzato se volevano farlo. – Jay

+0

@ Jay, il tuo suggerimento su Record è esattamente ciò che intendo. – AlexR

2

Perché avresti ancora bisogno di un'altra funzione per recuperare il valore, quindi non si otterrebbe nulla.

In un ResultSet, next() porta al record successivo o restituisce false se non ce n'è. Quindi fai getString(), getInt() o qualsiasi altra cosa per recuperare i valori del campo. Così si scrive il codice del tipo:

while (rs.next()) 
{ 
    name=rs.getString("name"); // or whatever 
    ... do something with name ... 
} 

In un Iterator, hasNext() restituisce un vero o falso per indicare se c'è un altro record. Quindi si chiama next() per recuperare il valore. così si scrive il codice del tipo:

while (iter.hasnext()) 
{ 
    name=iter.next(); // or whatever 
    ... do something with name ... 
} 

Il modello finisce per essere piuttosto simili. È un peccato che le implementazioni siano incoerenti. Vale a dire, ResultSet.next non solo ti dice se sei alla fine ma avanza anche il positoin, mentre Iterator.hasNext ti dice se sei alla fine ma non avanza la posizione. Ma l'uso effettivo è abbastanza simile.

Non sarebbe davvero utile provare a combinare Iterator.hasNext e Iterator.next in un'unica funzione. Come faresti a sapere quando hai raggiunto la fine? Si potrebbe dire che restituisce null alla fine ... ma cosa succede se null è un valore valido nella lista? Suppongo che potresti aggiungere un po 'di valore magico, ma avresti comunque il problema di distinguere il significato magico da una voce nella lista che è appena capita di avere quel valore. Come se tu avessi una lista di ints, potresti dire che -1 significa end-of-list, ma che succede se l'elenco include un valore di -1?

L'unica altra alternativa che vedo è che la funzione next() restituisca un oggetto che include sia un'indicazione di fine elenco che, se applicabile, il valore. Ma questo sarebbe un dolore da usare. Dovresti scrivere qualcosa del tipo:

while (true) 
{ 
    IterableResult ir=iter.next(); 
    if (ir.end) 
    { 
    break; 
    } 
    else 
    { 
    name=ir.value; 
    ... do something with name ... 
    } 
} 

Questo non sembra guadagnare nulla.

Forse c'è un altro approccio che funzionerebbe meglio, ma non riesco a pensarne uno. E a quanto pare anche i creatori dell'interfaccia Iterator non hanno potuto pensare a un modo migliore! :-)

+0

Beh, c'è differenza. ResultSet non fa qualcosa come first getRecord e quindi getXXX su un oggetto record. Sposta il cursore sull'oggetto successivo nella singola istruzione e accedi ai membri di quell'oggetto con i metodi getXXX(). In realtà non si ottiene l'intero oggetto record con i metodi getXXX. – Delta

+0

@Delta Assolutamente vero. Ma l'utilizzo sarebbe ancora simile. – Jay