pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

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

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

問(wèn)題描述

可能重復(fù):
為什么Java的Iterator不是Iterable?

給定for-each循環(huán)的慣用方式迭代器?

我們可以使用用于迭代Iterator類(lèi)型對(duì)象的for-each循環(huán)?

據(jù)我所知,foreach 循環(huán)是 Java 5 中添加的語(yǔ)法糖.所以

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
}

基本上會(huì)產(chǎn)生與

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

但是,如果我一開(kāi)始沒(méi)有可迭代對(duì)象,而只有一個(gè)迭代器(比如說(shuō),因?yàn)橐粋€(gè)類(lèi)提供了兩個(gè)不同的迭代器),我就不能使用語(yǔ)法糖 foreach 循環(huán).顯然我仍然可以進(jìn)行簡(jiǎn)單的舊樣式迭代.但是,我實(shí)際上想做:

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
}

當(dāng)然我可以做一個(gè)假的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;
    }
}

(這實(shí)際上是對(duì) Iterable API 的丑陋濫用,因?yàn)樗荒艿淮危?

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

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

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.

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

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?

還是有一些我不知道的語(yǔ)言技巧?

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

推薦答案

所以我現(xiàn)在有了一個(gè)比較合理的解釋:

So I have a somewhat reasonable explanation now:

短版:因?yàn)檎Z(yǔ)法也適用于沒(méi)有迭代器的數(shù)組.

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

如果語(yǔ)法是按照我的建議圍繞 Iterator 設(shè)計(jì)的,它將與數(shù)組不一致.讓我給出三個(gè)變體:

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

A) 由 Java 開(kāi)發(fā)人員選擇:

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(); }

行為方式相同,并且在數(shù)組和集合之間高度一致.然而,迭代器必須使用經(jīng)典的迭代風(fēng)格(至少不會(huì)導(dǎo)致錯(cuò)誤).

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) 允許數(shù)組和Iterators:

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

現(xiàn)在數(shù)組和集合不一致;但是數(shù)組和 ArrayList 密切相關(guān),應(yīng)該表現(xiàn)相同.現(xiàn)在,如果在任何時(shí)候,該語(yǔ)言將被 擴(kuò)展 以制作例如數(shù)組實(shí)現(xiàn)了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) 允許所有三個(gè):

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

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

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.

現(xiàn)在突然間,我們需要注意是要迭代集合/可迭代對(duì)象還是數(shù)組,此時(shí)我們以大混亂為代價(jià)獲得了很少的好處.

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"的方式非常一致,它導(dǎo)致的編程錯(cuò)誤非常少,并且允許將來(lái)可能將數(shù)組轉(zhuǎn)換為常規(guī)對(duì)象.

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.

有一個(gè)變體 D) 可能也可以正常工作:for-each 僅適用于迭代器.最好通過(guò)向原始數(shù)組添加 .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) { }

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

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) { }

只對(duì)數(shù)據(jù)進(jìn)行一次迭代.

Only iterates over the data once.

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

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

相關(guān)文檔推薦

Java Remove Duplicates from an Array?(Java從數(shù)組中刪除重復(fù)項(xiàng)?)
How to fix Invocation failed Unexpected Response from Server: Unauthorized in Android studio(如何修復(fù)調(diào)用失敗來(lái)自服務(wù)器的意外響應(yīng):在 Android 工作室中未經(jīng)授權(quán))
AES encryption, got extra trash characters in decrypted file(AES 加密,解密文件中有多余的垃圾字符)
AES Error: Given final block not properly padded(AES 錯(cuò)誤:給定的最終塊未正確填充)
Detecting incorrect key using AES/GCM in JAVA(在 JAVA 中使用 AES/GCM 檢測(cè)不正確的密鑰)
AES-256-CBC in Java(Java 中的 AES-256-CBC)
主站蜘蛛池模板: 水稻烘干机,小麦烘干机,大豆烘干机,玉米烘干机,粮食烘干机_巩义市锦华粮食烘干机械制造有限公司 水环真空泵厂家,2bv真空泵,2be真空泵-淄博真空设备厂 | 杭州双螺杆挤出机-百科| 武汉EPS线条_EPS装饰线条_EPS构件_湖北博欧EPS线条厂家 | HYDAC过滤器,HYDAC滤芯,现货ATOS油泵,ATOS比例阀-东莞市广联自动化科技有限公司 | 杭州可当科技有限公司—流量卡_随身WiFi_AI摄像头一站式解决方案 | 柴油发电机组_柴油发电机_发电机组价格-江苏凯晨电力设备有限公司 | 煤棒机_增碳剂颗粒机_活性炭颗粒机_木炭粉成型机-巩义市老城振华机械厂 | 步进驱动器「一体化」步进电机品牌厂家-一体式步进驱动 | 搜活动房网—活动房_集装箱活动房_集成房屋_活动房屋 | 机构创新组合设计实验台_液压实验台_气动实训台-戴育教仪厂 | 馋嘴餐饮网_餐饮加盟店火爆好项目_餐饮连锁品牌加盟指南创业平台 | 台式恒温摇床价格_大容量恒温摇床厂家-上海量壹科学仪器有限公司 | 联系我们-腾龙公司上分客服微信19116098882 | 超声波乳化机-超声波分散机|仪-超声波萃取仪-超声波均质机-精浩机械|首页 | 橡胶膜片,夹布膜片,橡胶隔膜密封,泵阀设备密封膜片-衡水汉丰橡塑科技公司网站 | 发电机价格|发电机组价格|柴油发电机价格|柴油发电机组价格网 | 不锈钢螺丝 - 六角螺丝厂家 - 不锈钢紧固件 - 万千紧固件--紧固件一站式采购 | 预制直埋蒸汽保温管-直埋管道-聚氨酯发泡保温管厂家 - 唐山市吉祥保温工贸有限公司 | 板框压滤机-隔膜压滤机-厢式压滤机生产厂家-禹州市君工机械设备有限公司 | 全自动烧卖机厂家_饺子机_烧麦机价格_小笼汤包机_宁波江北阜欣食品机械有限公司 | 中国品牌排名投票_十大品牌榜单_中国著名品牌【中国品牌榜】 | 合肥通道闸-安徽车牌识别-人脸识别系统厂家-安徽熵控智能技术有限公司 | 石家庄救护车出租_重症转院_跨省跨境医疗转送_活动赛事医疗保障_康复出院_放弃治疗_腾康26年医疗护送转诊团队 | 合肥活动房_安徽活动板房_集成打包箱房厂家-安徽玉强钢结构集成房屋有限公司 | 热工多功能信号校验仪-热电阻热电偶校验仿真仪-金湖虹润仪表 | 宁夏活性炭_防护活性炭_催化剂载体炭-宁夏恒辉活性炭有限公司 | 信阳市建筑勘察设计研究院有限公司 | YAGEO国巨电容|贴片电阻|电容价格|三星代理商-深圳市巨优电子有限公司 | 法兰连接型电磁流量计-蒸汽孔板节流装置流量计-北京凯安达仪器仪表有限公司 | 仓储笼_仓储货架_南京货架_仓储货架厂家_南京货架价格低-南京一品仓储设备制造公司 | 无负压供水设备,消防稳压供水设备-淄博创辉供水设备有限公司 | 污泥烘干机-低温干化机-工业污泥烘干设备厂家-焦作市真节能环保设备科技有限公司 | 除尘器布袋骨架,除尘器滤袋,除尘器骨架,电磁脉冲阀膜片,卸灰阀,螺旋输送机-泊头市天润环保机械设备有限公司 | 常州律师事务所_常州律所_常州律师-江苏乐天律师事务所 | 贵州科比特-防雷公司厂家提供贵州防雷工程,防雷检测,防雷接地,防雷设备价格,防雷产品报价服务-贵州防雷检测公司 | 压力喷雾干燥机,喷雾干燥设备,柱塞隔膜泵-无锡市闻华干燥设备有限公司 | 烟雾净化器-滤筒除尘器-防爆除尘器-除尘器厂家-东莞执信环保科技有限公司 | 首页|专注深圳注册公司,代理记账报税,注册商标代理,工商变更,企业400电话等企业一站式服务-慧用心 | 国际线缆连接网 - 连接器_线缆线束加工行业门户网站 | 硅胶布|电磁炉垫片|特氟龙胶带-江苏浩天复合材料有限公司 | 硅PU球场、篮球场地面施工「水性、环保、弹性」硅PU材料生产厂家-广东中星体育公司 |