2012-03-14 33 views
5

Trong giao diện ResultSetnext phương pháp mà trở boolean và sau đó bạn có thể trực tiếp truy cập vào kỷ lục hiện tại bằng cách get phương phápIterator phương pháp tiếp theo

Tại sao Iterator từ java.util chỉ không thả hasNext() phương pháp và chỉ có next phương pháp đó sẽ di chuyển con trỏ đến phần tử tiếp theo và trả về boolean?

+0

Tôi đã thử một cái gì đó như thế này trong khi ((o = itr.next())! = Null), tôi nhận được NoSuchElementException. Nếu bạn thấy việc thực hiện phương thức iterator() trong các lớp khác nhau, bạn sẽ thấy NoSuchELementException được ném bằng cách kiểm tra điều kiện khác nhau. Ví dụ, Abstractlist có khối catch đẹp của IndexOutOfBoundsException để ném NoSuchElementException và trong lớp LinkedBlockingDeque chúng ta có tiếp theo! = Null kiểm tra – Delta

Trả lời

8

next() hiện trả về mục tiếp theo.

Java thể đã triển khai mô hình lặp trong cùng một cách mà .NET không, với một MoveNext() trả lại một giá trị Boolean, và sau đó một tài sản với giá trị "hiện tại" Current - nhưng nó vẫn còn hai thành viên ...

Phương án thay thế khác là có một giá trị trả về chứa hai ý tưởng là "có giá trị" và "giá trị nếu có" - một loại Maybe, thật vậy. Tất nhiên trong Java, điều đó có nghĩa là phân bổ một đối tượng mới trên mỗi lần lặp, mà không phải là lý tưởng ...

0

Phương thức giống như hasNext() của trình lặp. Phần lớn các phương thức khác của ResultSet thay vì phương thức Iterator đơn next().

Tôi muốn đặt câu hỏi khác: tại sao họ không thực hiện ResultSet triển khai trình lặp hoặc ít nhất có thể lặp lại với generics? Tôi nghĩ câu trả lời là ResultSet xuất hiện trong java trước Iterator. Ngay sau đó rất nhiều công cụ giống như ORM đã được giới thiệu, vì vậy hầu hết mọi người chỉ không sử dụng JDBC trực tiếp và không đối phó với ResultSet.

Nhưng tôi không phải là nhà sử học JDK, vì vậy đó là giả định của tôi.

+0

Ngoài ra, Iterable.next trả về một giá trị duy nhất, trong khi sau khi thực hiện một ResultSet.next bạn có thể làm nhiều getXXX để lấy nhiều giá trị. Tôi cho rằng ResultSet có thể đã được thực hiện như một Iterator trả về một đối tượng "Record", và sau đó bạn kéo các trường ra khỏi Record. Tôi cho rằng điều đó sẽ phù hợp hơn. – Jay

+1

Đúng là ResultSet nằm trong Java trước Iterator, nhưng Java đã có Enumeration kể từ phiên bản 1.0, là phiên bản tiền nhiệm của Iterator và có thể đã được sử dụng nếu họ muốn làm điều đó. – Jay

+0

@Jay, đề xuất của bạn về Bản ghi chính xác là ý tôi. – AlexR

2

Vì bạn vẫn cần một hàm khác để truy xuất giá trị, vì vậy không có gì có thể đạt được.

Trong ResultSet, next() đưa bạn đến bản ghi tiếp theo hoặc trả về false nếu không có. Sau đó, bạn làm getString(), getInt() hoặc bất cứ điều gì để lấy giá trị trường. Vì vậy, bạn viết mã như sau:

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

Trong Iterator, hasNext() trả về giá trị đúng hoặc sai để cho biết nếu có một bản ghi khác. Sau đó, bạn gọi next() để lấy giá trị. vì vậy, bạn viết mã như:

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

Mẫu kết thúc tương tự. Thật không may là việc triển khai không nhất quán. Đó là, ResultSet.next không chỉ cho bạn biết nếu bạn đang ở cuối mà còn tiến bộ các positoin, trong khi Iterator.hasNext cho bạn biết nếu bạn đang ở cuối nhưng không thăng tiến vị trí. Nhưng thực tế sử dụng là khá giống nhau.

Nó sẽ không thực sự làm việc để cố gắng kết hợp Iterator.hasNext và Iterator.next vào một hàm. Làm thế nào bạn sẽ biết khi bạn đạt đến kết thúc? Bạn có thể nói rằng nó trả về null ở cuối ... nhưng nếu null là giá trị hợp lệ trong danh sách thì sao? Tôi cho rằng bạn có thể thêm một số giá trị ma thuật, nhưng bạn vẫn có vấn đề phân biệt ý nghĩa ma thuật từ một mục trong danh sách vừa xảy ra để có giá trị đó. Giống như nếu bạn có một danh sách các int, bạn có thể nói rằng -1 có nghĩa là kết thúc của danh sách, nhưng sau đó những gì nếu danh sách bao gồm một giá trị -1?

Cách duy nhất khác mà tôi thấy là để hàm next() trả về một đối tượng bao gồm cả chỉ báo cuối danh sách và, nếu có, giá trị. Nhưng điều này sẽ là một nỗi đau để sử dụng. Bạn phải viết một cái gì đó như:

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

Điều đó dường như không đạt được gì.

Có thể có một cách tiếp cận khác có thể hoạt động tốt hơn, nhưng tôi không thể nghĩ ra. Và dường như những người sáng tạo của giao diện Iterator cũng không thể nghĩ ra một cách tốt hơn! :-)

+0

Cũng có sự khác biệt. ResultSet không làm một cái gì đó như getRecord đầu tiên và sau đó làm getXXX trên đối tượng bản ghi. Nó di chuyển con trỏ đến đối tượng tiếp theo trong câu lệnh đơn và bạn truy cập các thành viên của đối tượng đó bằng phương thức getXXX(). Bạn không thực sự nhận được toàn bộ đối tượng bản ghi bằng phương thức getXXX. – Delta

+0

@Delta Hoàn toàn đúng. Nhưng việc sử dụng sẽ vẫn tương tự. – Jay

Các vấn đề liên quan