在Java中,我需要从我的方法返回一个Iterator。我的数据来自另一个通常可以给我一个迭代器的对象,所以我可以返回它,但在某些情况下,底层数据为null。为了保持一致性,我想返回一个<!> quot; empty <!> quot;在这种情况下迭代器,所以我的调用者不必测试null。

我想写一些类似的东西:

public Iterator<Foo> iterator() {
   if (underlyingData != null) {
      return underlyingData.iterator();  // works
   } else {
      return Collections.emptyList().iterator();  // compiler error
   }
}

但Java编译器抱怨返回Iterator<Object>而不是Iterator<Foo>。转换为(Iterator<Foo>)也不起作用。

有帮助吗?

解决方案

您可以通过以下语法获取Foo类型的空列表:

return Collections.<Foo>emptyList().iterator();

其他提示

Java 7已经出现了很长时间。除非您正在为以前的Java版本开发,否则您将返回一个如下所示的空迭代器:

return Collections.emptyIterator();

我会更多地遵循

public Iterator<Foo> iterator() {
    if (underlyingData == null)
        return Collections.<Foo> emptyList().iterator();
    return underlyingData.iterator();
}

只是,处理特殊情况并返回,然后处理正常情况。但我的主要观点是你可以用

来避免作业
Collections.<Foo> emptyList().iterator();

Collections.<Foo>emptyList().iterator()的烦恼是我们在 google-collections 中提供Iterators.emptyIterator()的主要原因。在像你这样的情况下,不需要类型参数。

我想这表明Java类型推断在每种情况下都不起作用,并且三元运算符并不总是等同于明显等效的if-else结构。

我还要声明避免null 。还要避免传递Iterator s,因为它们有奇怪的有状态行为(更喜欢Iterable)。但是,假设你有一个合理的,非过早的理由这样做,我首选的写作方式是

public Iterator<Foo> iterator() {
    return getUnderlyingData().iterator();
}
private List<Foo> getUnderlyingData() {
    if (underlyingData == null) {
        return Collections.emptyList();
    } else {
        return underlyingData;
    }
}

IMO,如果可以推断,最好不要插入可推断类型信息(即使它使你的代码更长)。

您几乎肯定会多次执行此操作,因此请插入getUnderlyingData方法,而不是仅声明局部变量。

你在两个结果上都打电话给iterator,所以不要重复。

抱歉,我明白了。您需要使用赋值,以便编译器可以找出参数化类型。

public Iterator<Foo> iterator() {
   if (underlyingData != null) {
      return underlyingData.iterator();
   } else {
      List<Foo> empty = Collections.emptyList();  // param type inference
      return empty.iterator();
   }
}
public  final class EmptyIterator{

    public static Iterator iterator(){
        return new Empty();
    }

    private static class Empty implements Iterator {
        public boolean hasNext(){
            return false;
        }
        public Object next(){
            throw new NoSuchElementException();
        }
        public void remove(){
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top