久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

為什么 Java 不允許在迭代器上使用 foreach(僅在可

Why does Java not allow foreach on iterators (only on iterables)?(為什么 Java 不允許在迭代器上使用 foreach(僅在可迭代對象上)?)
本文介紹了為什么 Java 不允許在迭代器上使用 foreach(僅在可迭代對象上)?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

可能重復:
為什么Java的Iterator不是Iterable?

給定for-each循環的慣用方式迭代器?

我們可以使用用于迭代Iterator類型對象的for-each循環?

據我所知,foreach 循環是 Java 5 中添加的語法糖.所以

The foreach loop are as far as I know syntax sugar added in Java 5. So

Iterable<O> iterable;
for(O o : iterable) {
    // Do something
}

基本上會產生與

Iterable<O> iterable;
for(Iterator<O> iter = iterable.iterator(); iter.hasNext(); /* NOOP */) {
    O o = iter.next();
    // Do something
}

但是,如果我一開始沒有可迭代對象,而只有一個迭代器(比如說,因為一個類提供了兩個不同的迭代器),我就不能使用語法糖 foreach 循環.顯然我仍然可以進行簡單的舊樣式迭代.但是,我實際上想做:

However, if I do not have an iterable in the first place, but only an iterator (say, because a class offers two different iterators), I cannot use the syntax sugar foreach loop. Obviously I can still do the plain old style iteration. However, I'd actually like to do:

Iterator<O> iter;
for(O o : iter /* Iterator<O>, not Iterable<O>! */) {
     // Do something
}

當然我可以做一個假的Iterable:

And of course I can do a fake Iterable:

class Adapter<O> implements Iterable<O> {
    Iterator<O> iter;

    public Adapter(Iterator<O> iter) {
        this.iter = iter;
    }

    @Override
    public Iterator<O> iterator() {
        return iter;
    }
}

(這實際上是對 Iterable API 的丑陋濫用,因為它只能迭代一次!)

(Which in fact is an ugly abuse of the Iterable API, as it can only be iterated once!)

如果它是圍繞 Iterator 而不是 iterable 設計的,可以做很多有趣的事情:

If it were designed around Iterator instead of iterable, one could do a number of interesting things:

for(O o : iterable.iterator()) {} // Iterate over Iterable and Collections

for(O o : list.backwardsIterator()) {} // Or backwards

Iterator<O> iter;
for(O o : iter) {
    if (o.something()) { iter.remove(); }
    if (o.something()) { break; }
}
for(O : iter) { } // Do something with the remaining elements only.

有人知道為什么語言是這樣設計的嗎?如果一個類同時實現 IteratorIterable,為了避免歧義?為了避免假定for(O o : iter)"的程序員錯誤;將處理所有元素兩次(并忘記獲取新的迭代器)?還是有其他原因?

Does anyone know why the language was designed this way? To avoid ambiguity if a class would implement both Iterator and Iterable? To avoid programmer errors that assume that "for(O o : iter)" will process all elements twice (and forget to get a fresh iterator)? Or is there some other reason for this?

還是有一些我不知道的語言技巧?

Or is there some language trick I just do not know?

推薦答案

所以我現在有了一個比較合理的解釋:

So I have a somewhat reasonable explanation now:

短版:因為語法也適用于沒有迭代器的數組.

Short version: Because the syntax also applies to arrays, which don't have iterators.

如果語法是按照我的建議圍繞 Iterator 設計的,它將與數組不一致.讓我給出三個變體:

If the syntax were designed around Iterator as I proposed, it would be inconsistent with arrays. Let me give three variants:

A) 由 Java 開發人員選擇:

A) as chosen by the Java developers:

Object[] array;
for(Object o : array) { }
Iterable<Object> list;
for(Object o : list) { }
Iterator<Object> iter;
while(iter.hasNext()) { Object o = iter.next(); }

行為方式相同,并且在數組和集合之間高度一致.然而,迭代器必須使用經典的迭代風格(至少不會導致錯誤).

The behaves the same way and is highly consistent across arrays and collections. Iterators however have to use the classic iteration style (which at least is not likely to cause errors).

B) 允許數組和Iterators:

Object[] array;
for(Object o : array) { }
Iterable<Object> list;
for(Object o : list.iterator()) { }
Iterator<Object> iter;
for(Object o : iter) { }

現在數組和集合不一致;但是數組和 ArrayList 密切相關,應該表現相同.現在,如果在任何時候,該語言將被 擴展 以制作例如數組實現了Iterable,就變得不一致了.

Now arrays and collections are inconsistent; but arrays and ArrayList are very closely related and should behave the same way. Now if at any point, the language is extended to make e.g. arrays implement Iterable, it becomes inconsistent.

C) 允許所有三個:

Object[] array;
for(Object o : array) { }
Iterable<Object> list;
for(Object o : list) { }
Iterator<Object> iter;
for(Object o : iter) { }

現在,如果我們最終處于不清楚的情況下,當有人實現 both IterableIterator 時(for 循環是否應該得到一個新的迭代器或迭代當前 - 在樹狀結構中很容易發生!?!).不幸的是,一個簡單的 tie-braker ala Iterable beats Iterator"是行不通的:它突然引入了運行時與編譯時間差異和泛型問題.

Now if we end up in unclear situations when either someone implements both Iterable and Iterator (is the for loop supposed to get a new iterator or iterate over the current - happens easily in tree-like structures!?!). A simple tie-braker ala "Iterable beats Iterator" unfortunately won't do: it suddenly introduces runtime vs. compile time difference and generics issues.

現在突然間,我們需要注意是要迭代集合/可迭代對象還是數組,此時我們以大混亂為代價獲得了很少的好處.

Now suddenly, we need to pay attention to whether we want to iterate over collections/iterables or arrays, at which point we have gained very little benefits at the cost of a big confusion.

Java (A) 中for each"的方式非常一致,它導致的編程錯誤非常少,并且允許將來可能將數組轉換為常規對象.

The way "for each" is in Java (A) is very consistent, it causes very little programming errors, and it allows for the possible future change of turning arrays into regular objects.

有一個變體 D) 可能也可以正常工作:for-each 僅適用于迭代器.最好通過向原始數組添加 .iterator() 方法:

There is a variant D) that would probably also work okay: for-each for Iterators only. Preferrably by adding a .iterator() method to primitive arrays:

Object[] array;
for(Object o : array.iterator()) { }
Iterable<Object> list;
for(Object o : list.iterator()) { }
Iterator<Object> iter;
for(Object o : iter) { }

但這需要更改運行時環境,而不僅僅是編譯器,并且會破壞向后兼容性.另外,上面提到的混淆仍然存在,

But this requires changes to the runtime environment, not just the compiler, and breaks backwards compatibility. Plus, the mentioned confusion is still present that

Iterator<Object> iter;
for(Object o : iter) { }
for(Object o : iter) { }

只對數據進行一次迭代.

Only iterates over the data once.

這篇關于為什么 Java 不允許在迭代器上使用 foreach(僅在可迭代對象上)?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Java Remove Duplicates from an Array?(Java從數組中刪除重復項?)
How to fix Invocation failed Unexpected Response from Server: Unauthorized in Android studio(如何修復調用失敗來自服務器的意外響應:在 Android 工作室中未經授權)
AES encryption, got extra trash characters in decrypted file(AES 加密,解密文件中有多余的垃圾字符)
AES Error: Given final block not properly padded(AES 錯誤:給定的最終塊未正確填充)
Detecting incorrect key using AES/GCM in JAVA(在 JAVA 中使用 AES/GCM 檢測不正確的密鑰)
AES-256-CBC in Java(Java 中的 AES-256-CBC)
主站蜘蛛池模板: 99精品欧美一区二区三区 | 色播久久久| 精品欧美一区二区三区 | 7799精品视频天天看 | 日韩欧美国产一区二区 | 日韩久久综合网 | 国产一区二区在线播放 | 免费视频一区二区 | 亚洲欧美日韩精品久久亚洲区 | 亚洲综合一区二区三区 | 一区二区成人 | 凹凸日日摸日日碰夜夜 | 午夜精品一区二区三区在线视频 | 81精品国产乱码久久久久久 | 亚洲欧美一区二区三区情侣bbw | 久草在线中文888 | 人妖av| 日韩精品一区二区三区老鸭窝 | 日韩二三区 | 亚洲高清网 | 国内久久精品 | 精品网站999www| 成人国产在线视频 | 中文字幕中文字幕 | 国产成人综合网 | 久久久久久综合 | 欧产日产国产精品国产 | 久久久久久国产精品久久 | 亚洲人成在线观看 | 在线免费观看黄视频 | 日韩av免费在线观看 | 中文字幕韩在线第一页 | 精品视频久久久 | 久久性色 | 亚洲精选一区 | 亚洲国产一 | av网站免费| 狠狠操电影 | 国产成都精品91一区二区三 | 欧美日韩第一页 | 免费看黄色国产 |