2012-03-14 8 views
5

En ResultSet interfaz no es next método que volver booleano y luego se puede acceder directamente al registro actual por get métodositerador método siguiente

Por qué Iterator de java.util simplemente deje caer hasNext() método y sólo tienen next método que se moverá el cursor al siguiente elemento y devolver boolean?

+0

Intenté algo así mientras ((o = itr.next())! = Null), obtuve NoSuchElementException. Si ve la implementación del método iterator next() en varias clases, verá NoSuchELementException arrojando una condición diferente. Por ejemplo, Abstractlist tiene un hermoso bloque catch de IndexOutOfBoundsException para lanzar NoSuchElementException y en la clase LinkedBlockingDeque tenemos next! = Null check – Delta

Respuesta

8

Porque next() actualmente devuelve el siguiente artículo.

Java podía han implementado el iterador de la misma manera que lo hace .NET, con un MoveNext() devolver un valor booleano, y luego un Current propiedad con el valor "actual" - pero sigue siendo dos miembros ...

La otra alternativa es tener un valor de retorno que encapsula las dos ideas de "¿hay algún valor?" Y "¿cuál es el valor si hay una?" - una especie de tipo Maybe, realmente. Por supuesto, en Java, eso significa que la asignación de un nuevo objeto en cada iteración, que no es ideal ...

0

El método de ResultSetnext() es como hasNext() del iterador. La mayoría de los otros métodos de ResultSet son en vez del único next() método de iterador.

Me gustaría hacer otra pregunta: ¿por qué no hicieron ResultSet implementar iterator o al menos iterable con genéricos? Creo que la respuesta es que ResultSet aparece en Java antes de Iterator. Poco después, se introdujeron muchas herramientas similares a ORM, por lo que la mayoría de las personas simplemente no usan JDBC directamente y no se ocupan de ResultSet.

Pero no soy historiador de JDK, por lo que es mi suposición.

+0

Además, Iterable.next devuelve un solo valor, mientras que después de hacer un ResultSet.next puedes hacer muchos getXXX para recuperar muchos valores. Supongo que ResultSet podría haberse implementado como un iterador que devuelve un objeto "Grabar" y luego sacar los campos del registro. Supongo que habría sido más consistente. – Jay

+1

Es cierto que ResultSet estaba en Java antes de Iterator, pero Java ha tenido Enumeration desde la versión 1.0, que es el predecesor de Iterator y podría haber sido utilizado si quisieran hacer eso. – Jay

+0

@Jay, tu sugerencia sobre Record es exactamente lo que quiero decir. – AlexR

2

Porque todavía necesitaría otra función para recuperar el valor, por lo que no se ganaría nada.

En un ResultSet, next() lo lleva al siguiente registro, o devuelve falso si no hay ninguno. Luego obtiene getString() 's, getInt()' s o lo que sea para recuperar valores de campo. Así se escribe código como:

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

En un iterador, hasNext() devuelve un verdadero o falso para indicar si hay otro registro. Luego llama a next() para recuperar el valor. para que escriba código como:

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

El patrón termina siendo bastante similar. Es desafortunado que las implementaciones sean inconsistentes. Es decir, ResultSet.next no solo te dice si estás al final sino que también avanza la posición posterior, mientras que Iterator.hasNext te dice si estás al final pero no avanza la posición. Pero el uso real es bastante similar.

Realmente no funcionaría tratar de combinar Iterator.hasNext y Iterator.next en una sola función. ¿Cómo sabrías cuándo alcanzaste el final? Podría decir que devuelve nulo al final ... pero ¿qué ocurre si null es un valor válido en la lista? Supongo que podría agregar algún valor mágico, pero aún tendría el problema de distinguir el significado mágico de una entrada en la lista que acaba de tener ese valor. Al igual que si tiene una lista de entradas, podría decir que -1 significa final de lista, pero ¿qué ocurre si la lista incluye un valor de -1?

La única otra alternativa que veo es hacer que la función next() devuelva un objeto que incluye tanto una indicación de fin de lista como, si corresponde, el valor. Pero esto sería un dolor de usar. Tendría que escribir algo como:

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

Eso no parece ganar nada.

Quizás haya otro enfoque que funcionaría mejor, pero no puedo pensar en uno. ¡Y aparentemente los creadores de la interfaz Iterator tampoco pudieron pensar en una mejor manera! :-)

+0

Bueno, hay una diferencia. ResultSet no hace algo como getRecord primero y luego getXXX en objeto de registro. Mueve el cursor al siguiente objeto en una sola instrucción y accede a los miembros de ese objeto mediante los métodos getXXX(). En realidad, no obtienes un objeto de registro completo mediante métodos getXXX. – Delta

+0

@Delta Absolutamente cierto. Pero el uso aún sería similar. – Jay