Java:为什么不能遍历迭代器? [英] Java: why can't iterate over an iterator?

查看:155
本文介绍了Java:为什么不能遍历迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过为什么Java的Iterator不是Iterable?为什么枚举不可用?,但我仍然不明白为什么:

I read Why is Java's Iterator not an Iterable? and Why aren't Enumerations Iterable?, but I still don't understand why this:

void foo(Iterator<X> it) {
  for (X x : it) {
    bar(x);
    baz(x);
  }
}

无法实现。换句话说,除非我遗漏了某些内容,否则以上内容可能是很好且有效的语法糖:

was not made possible. In other words, unless I'm missing something, the above could have been nice and valid syntactic sugar for:

void foo(Iterator<X> it) {
  for (X x; it.hasNext();) {
    x = it.next();
    bar(x);
    baz(x);
  }
}


推荐答案


但我仍然不明白为什么 [...] 无法实现。

我可以看到以下几个原因:

I can see several reasons:


  1. Iterator s不是可重用,所以for / each会消耗迭代器 - 也许不是不正确的行为,但对于那些不知道for / each如何被淘汰的人来说是不直观的。

  2. 迭代器 s在代码中看起来并不是裸,因此它会使JLS变得非常复杂(for / each结构很糟糕,因为它们正在处理 Iterable s和数组)。

  3. 有一个简易解决方法。为此分配一个新对象似乎有点浪费,但分配很便宜,逃避分析在大多数情况下甚至可以消除你的成本。 (为什么他们没有在 Iterables 实用程序类中包含此变通方法,类似于集合阵列,超出了我的范围。)

  4. (可能不正确 - 请参阅评论。)我似乎记得JLS只能参考 java.lang [citation needed] ,所以他们必须创建一个 Iterator 接口在 java.lang 哪个 java.util.Iterator 扩展而不添加任何内容。现在我们有两个功能相当的迭代器接口。使用裸迭代器的新代码的50%将选择 java.lang 版本,其余使用中的一个java.util 。随之而来的是混乱,兼容性问题比比皆是等。

  1. Iterators are not reusable, so a for/each would consume the iterator - not incorrect behavior, perhaps, but unintuitive to those who don't know how the for/each is desugared.
  2. Iterators don't appear "naked" in code all that often so it would be complicating the JLS with little gain (the for/each construct is bad enough as it is, working on both Iterables and arrays).
  3. There's an easy workaround. It may seem a little wasteful to allocate a new object just for this, but allocation is cheap as it is and escape analysis would rid you even of that small cost in most cases. (Why they didn't include this workaround in an Iterables utility class, analogous to Collections and Arrays, is beyond me, though.)
  4. (Probably not true - see the comments.) I seem to recall that the JLS can only reference things in java.lang[citation needed], so they'd have to create an Iterator interface in java.lang which java.util.Iterator extends without adding anything to. Now we have two functionally equivalent iterator interfaces. 50% of the new code using naked iterators will choose the java.lang version, the rest use the one in java.util. Chaos ensues, compatibility problems abound, etc.

我认为第1-3点非常符合Java语言设计理念似乎如下:不要让新手感到惊讶,如果没有明显的收益来掩盖成本,请不要使规范复杂化,并且不要使用语言功能可以使用库来完成。

I think points 1-3 are very much in line with how the Java language design philosophy seems to go: Don't surprise newcomers, don't complicate the spec if it doesn't have a clear gain that overshadows the costs, and don't do with a language feature what can be done with a library.

相同的参数可以解释为什么 java.util.Enumeration 不是 Iterable 也是。

The same arguments would explain why java.util.Enumeration isn't Iterable, too.

这篇关于Java:为什么不能遍历迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆