ResultSet
接口中,有一个返回布尔值的 next
方法,然后您可以直接使用 get
方法访问当前记录。为什么来自
java.util
的 Iterator
不删除 hasNext()
方法,而只是有一个 next
方法将光标移动到下一个元素并返回 boolean
?ResultSet
接口中,有一个返回布尔值的 next
方法,然后您可以直接使用 get
方法访问当前记录。java.util
的 Iterator
不删除 hasNext()
方法,而只是有一个 next
方法将光标移动到下一个元素并返回 boolean
?由于next()
当前返回下一个项。
Java也可以像.NET一样以相同的方式实现迭代器模式,其中MoveNext()
返回布尔值,然后Current
属性带有“当前”值-但仍然是两个成员...
另一种选择是有一个返回值,封装了“是否有值”和“如果有值是什么”的两个概念-一种类型的Maybe
类型。当然在Java中,这意味着在每次迭代时分配一个新对象,这并不理想...
因为你仍然需要另一个函数来检索值,所以没有任何收益。
在ResultSet中, next()能帮助你跳转到下一条记录, 如果没有下一条记录就返回false。然后你可以用getString()、getInt()或者其他方式来检索字段值。所以你要写出以下代码:
while (rs.next())
{
name=rs.getString("name"); // or whatever
... do something with name ...
}
在迭代器中,hasNext()方法返回true或false,以指示是否有另一条记录。然后您调用next()方法来检索值。因此您写的代码如下:
while (iter.hasnext())
{
name=iter.next(); // or whatever
... do something with name ...
}
模式最终变得非常相似。不幸的是,实现不一致。也就是说,ResultSet.next 不仅告诉您是否已经到达末尾,而且还会推进位置,而 Iterator.hasNext 告诉您是否已经到达末尾,但不会推进位置。但实际使用方式非常相似。
将 Iterator.hasNext 和 Iterator.next 结合成一个函数并不会真正起作用。你怎么知道你到达了结尾?你可以说它在结尾处返回 null ... 但如果 null 是列表中的有效值呢?我想你可以添加一些魔法值,但你仍然有区分魔法含义和列表中恰好具有该值的条目的问题。例如,如果您有一个整数列表,您可以说 -1 表示列表结束,但是如果列表包括值为 -1 的值呢?
我看到的唯一其他选择是让 next() 函数返回一个对象,该对象包括列表结束指示以及(如果适用)该值。但这将很难使用。你必须写类似于:
while (true)
{
IterableResult ir=iter.next();
if (ir.end)
{
break;
}
else
{
name=ir.value;
... do something with name ...
}
}
看起来这并没有带来任何好处。
也许有其他更好的方法,但我想不到。而且显然,迭代器接口的创建者们也想不出更好的办法!:-)
ResultSet
的 next()
方法类似于迭代器的 hasNext()
方法。而 ResultSet
的大多数其他方法则是替代了迭代器的单个 next()
方法。
我想问另一个问题:为什么他们没有让 ResultSet
实现带泛型的迭代器或至少实现可迭代接口?我认为答案是因为在 Iterator 之前,ResultSet
就已经出现在 Java 中了。不久之后,出现了许多类似 ORM 的工具,所以大多数人都不直接使用 JDBC,也不处理 ResultSet
。
但我不是 JDK 的历史学家,这只是我的猜测。
ResultSet
的迭代可能会产生一个“预期”的异常,而使用 Iterator
则不会发生这种情况。 - Tom Hawtin - tackline