2012-03-14 21 views
5

W ResultSet interfejs jest next metoda, która zwraca wartość logiczna, a następnie można bezpośrednio uzyskać dostęp do aktualnego rekordu przez get metodIterator Kolejna metoda

Dlaczego Iterator z java.util prostu nie upuścić hasNext() metody i mają tylko next metodę, która będzie przesunąć kursor do następnego elementu i powrót boolean?

+0

Próbowałem czegoś takiego podczas ((o = itr.next())! = Null), dostałem NoSuchElementException. Jeśli zobaczysz implementację metody iterator next() w różnych klasach, zobaczysz wyjątek NoSuchELementException, sprawdzając inny warunek. Na przykład, Lista statystyk ma piękny blok catch obiektu IndexOutOfBoundsException, aby rzucić wyjątek NoSuchElementException, a w klasie LinkedBlockingDeque mamy następną! = Zerowa kontrola – Delta

Odpowiedz

8

Ponieważ next() obecnie zwraca następny element.

Java mógł wdrożyły wzór iterator w taki sam sposób, że .NET robi, z MoveNext() przekazujących wartość logiczną, a następnie Current nieruchomość na „aktualnym” wartość - ale to jeszcze dwóch członków ...

Inną alternatywą jest posiadanie jednej wartości zwracanej, która zawiera w sobie dwie koncepcje: "czy istnieje wartość" i "jaka jest wartość, jeśli istnieje" - tak naprawdę rodzaj typu Maybe. Oczywiście w Javie, czyli przydzielenie nowego obiektu na każdej iteracji, który nie jest idealny ...

0

next() metoda ResultSet jest jak hasNext() z iteracyjnej. Większość innych metod jest zamiast pojedynczego next() metody Iteratora.

Chciałbym zadać inne pytanie: dlaczego nie zrobili ResultSet zaimplementować iterator lub przynajmniej iterable z rodzajami? Myślę, że odpowiedź brzmi, że ResultSet pojawia się w java przed Iteratorem. Wkrótce potem wprowadzono wiele narzędzi podobnych do ORM, więc większość ludzi po prostu nie używa JDBC bezpośrednio i nie zajmuje się ResultSet.

Ale nie jestem historykiem JDK, więc to jest moje założenie.

+0

Ponadto, Iterable.next zwraca pojedynczą wartość, a po wykonaniu ResultSet.next można zrobić wiele getXXX, aby pobrać wiele wartości. Przypuszczam, że ResultSet mógł zostać zaimplementowany jako Iterator, który zwraca obiekt "Record", a następnie wyciągnąć pola z Record. Przypuszczam, że byłby bardziej spójny. – Jay

+1

To prawda, że ​​ResultSet był w Javie przed Iteratorem, ale Java miała wyliczenia od wersji 1.0, która jest poprzednikiem Iteratora i mogła zostać użyta, gdyby chciała to zrobić. – Jay

+0

@Jaj, twoja sugestia dotycząca Record jest dokładnie tym, o czym mówię. – AlexR

2

Ponieważ nadal potrzebna jest inna funkcja do pobrania wartości, więc nic nie zostanie uzyskane.

W ResultSet, next() przeniesie Cię do następnego rekordu lub zwróci false, jeśli nie ma żadnego. Następnie uzyskujesz wartości getString(), getInt() lub cokolwiek, aby pobrać wartości pól. Tak jak piszesz kod:

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

W iterator, hasNext() zwraca true lub false, aby wskazać, czy istnieje inny rekord. Następnie wywołaj next(), aby pobrać wartość. tak jak piszesz kod:

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

Wzorzec kończy się dość podobnie. To niefortunne, że implementacje są niespójne. Oznacza to, że ResultSet.next nie tylko informuje, czy jesteś na końcu, ale także zwiększa positoin, podczas gdy Iterator.hasNext mówi ci, czy jesteś na końcu, ale nie przesuwasz pozycji. Ale faktyczne użycie jest podobne.

Naprawdę nie działałoby, aby połączyć Iterator.hasNext i Iterator.next w jedną funkcję. Skąd wiesz, kiedy dotarłeś do końca? Można powiedzieć, że na koniec zwraca wartość null ... ale co jeśli null jest poprawną wartością na liście? Przypuszczam, że mógłbyś dodać trochę magicznej wartości, ale nadal masz problem z odróżnieniem magicznego znaczenia od wpisu na liście, który akurat miał taką wartość. Jeśli masz listę int, możesz powiedzieć, że -1 oznacza koniec listy, ale co jeśli lista zawiera wartość -1?

Jedyną alternatywą jaką widzę, to funkcja next() zwraca obiekt, który zawiera zarówno wskazanie końca listy, jak i, jeśli ma to zastosowanie, wartość. Ale byłby to trudny do użycia. Będziesz musiał napisać coś w stylu:

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

Wydaje się, że nic nie zyskuje.

Może istnieje inne podejście, które działałoby lepiej, ale nie mogę o nim myśleć. I najwyraźniej twórcy interfejsu Iteratora również nie mogli wymyślić lepszego sposobu! :-)

+0

Cóż, jest różnica. ResultSet nie robi czegoś takiego jak first getRecord, a następnie robi getXXX na obiekcie rekordowym. Przesuwa kursor do następnego obiektu w pojedynczej instrukcji i uzyskuje dostęp do członków tego obiektu metodami getXXX(). Właściwie nie otrzymujesz całego obiektu rekordu metodami getXXX. – Delta

+0

@Delta Absolutnie prawda. Ale użycie będzie nadal podobne. – Jay