Java 可迭代的:如果没有可迭代的内容,iterator() 是否可以返回 null?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24097059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:09:11  来源:igfitidea点击:

Iterable: may iterator() returns null in case there is nothing to iterate over?

javanulliterator

提问by mins

An object implementing Iterableinterface must have a method with this signature:

实现Iterable接口的对象必须具有具有此签名的方法:

Iterator<T> iterator()

o being an Iterable, is this code safe?

o 作为Iterable,此代码安全吗?

while(o.iterator().hasNext()) { ... }

In other terms, may iterator()returns null in case there is nothing to iterate over?

iterator()换句话说,如果没有什么可迭代的,可能会返回 null 吗?

EDIT:

编辑:

1- As some of you point out, the iterator returned is different each time o.iterator() is executed. Fair enough! I must agree that I had forgotten this point when writing the question.

1- 正如你们中的一些人指出的那样,每次执行 o.iterator() 时返回的迭代器都不同。很公平!我必须同意,我在写这个问题时忘记了这一点。

Let's say this line is rewritten:

假设这一行被重写:

Iterator<String> it = o.iterator();
....
....
while(it.hasNext() {...}

2- As some of you point out, this is bad programming practice to return null when the documentation for Iterable.iterator() says: "Returns an iterator over a set of elements of type T."

2- 正如你们中的一些人指出的那样,当 Iterable.iterator() 的文档说:“返回一组 T 类型元素的迭代器时,返回 null 是不好的编程习惯。”

However my question is about whether returning null is prevented directly or indirectly by some 'contract' in the Java API documentation. To me "Returns an iterator over a set of elements of type T" doesn't prevent returning null. I may be wrong.

但是,我的问题是关于 Java API 文档中的某些“合同”是否直接或间接阻止了返回 null。对我来说,“在一组 T 类型的元素上返回迭代器”并不能阻止返回 null。我可能是错的。

Conclusion from your answers and additional research

从您的回答和额外研究得出的结论

Overall: Java API has no mean to say if the iterator value may be null or not, unless by stating it explicitly in the documentation. In this case, nothing is stated, however good sense allows to think that a null iterator value will never be returned from Java API methods. This may be different for API written by individuals.

总体而言:Java API 无法说明迭代器值是否为空,除非在文档中明确说明。在这种情况下,什么都没有说,但是好的意思是可以认为空迭代器值永远不会从 Java API 方法返回。对于个人编写的 API,这可能会有所不同。

  • Nothing in the documentation prevents the returned value to be null (e.g. @NotNull)
  • In the Javadoc, many @Return are explicit when null is also to be anticipated
  • This questionis about null return values in general, interesting.
  • I've found an attemptfor a language to describe APIs, though it for .NET
  • 文档中没有任何内容阻止返回值为空(例如@NotNull)
  • 在 Javadoc 中,许多 @Return 是显式的,而 null 也是可以预期的
  • 这个问题一般是关于空返回值的,很有趣。
  • 我发现尝试用一种语言来描述 API,尽管它是针对 .NET

采纳答案by Pshemo

may iterator()returns nullin case there is nothing to iterate over?

如果没有可迭代的内容,可能会iterator()返回null吗?

nullmay be returned (there are no tools in Java to prevent you from doing that) but it never should be. Instead return Iterator which hasNext()method returns false.

null可能会返回(Java 中没有工具可以阻止您这样做),但永远不应该返回. 而是返回 IteratorhasNext()方法返回的方法false

You need to know that purpose of Iterableobjects is to be used with for-eachloop

您需要知道Iterable对象的目的是与for-each循环一起使用

for (Type item : IterableInstance){
    //handle 'item'
    System.out.println(item);
}

which is translated to something like

这被翻译成类似的东西

for(Iterator<Type> i = someList.iterator(); i.hasNext(); ) {
    Type item = i.next();

    //handle 'item'
    System.out.println(item);
}

So if iterator()returns nullyou will get NullPointerExceptionat i.hasNext()(since iwould hold null). To avoid NPE you need proper iterator instance which for hasNext()will return false(if there are no elements to iterate). This will prevent loop iterations.

所以,如果iterator()回报null,你会得到NullPointerExceptioni.hasNext()(因为i将持有null)。为了避免 NPE,您需要适当的迭代器实例,hasNext()它将返回false(如果没有要迭代的元素)。这将防止循环迭代。



Aside form that there is other problem in your code

除了你的代码中还有其他问题的表格

while(o.iterator().hasNext()) { ... }

What you are doing here is that each time condition is checked new iteratoris created because you are calling o.iterator()which will start to iterate from first element. In other words you are checking each time if first element exists, which can cause infinite loop if ois not empty.

您在这里所做的是每次检查条件时都会创建新的迭代器,因为您正在调用o.iterator()它将从第一个元素开始迭代。换句话说,您每次都在检查第一个元素是否存在,如果o不为空,则会导致无限循环。

What you need is

你需要的是

Iterator<SomeType> it = o.iterator();
while(it.hasNext()) { ... }

回答by Matt Ball

In other terms, may iterator()returns null in case there is nothing to iterate over?

iterator()换句话说,如果没有什么可迭代的,可能会返回 null 吗?

No. A correctimplementation of the Iterableinterface will never return nullfrom its iterator()method. It will return a non-null Iteratorwhose hasNext()method immediately returns false.

第一个正确实现的Iterable接口绝不会返回nulliterator()方法。它将返回一个非空值,IteratorhasNext()方法立即返回false

However:

然而:

is this code safe?

这段代码安全吗?

Sure, but it doesn't do what you think it does, because the contract of iterator()is to return a different iterator every time iterator()is called.

当然,但它并没有像你想象的那样做,因为契约iterator()是每次iterator()调用时返回一个不同的迭代器。