我一定是错过了什么。
在 Java 5 中,"for-each loop" statement (also called the enhanced for loop)被介绍了。似乎它主要是为了迭代Collections而引入的。任何实现 Iterable 的集合(或容器)类接口(interface)可以使用“for-each 循环”进行迭代。也许由于历史原因,Java 数组没有实现 Iterable 接口(interface)。但由于数组无处不在,javac 将接受在数组上使用 for-each 循环(生成相当于传统 for 循环的字节码)。
在 Java 8 中,forEach method被添加到 Iterable 接口(interface)作为 default 方法。这使得将 lambda 表达式传递给集合(在迭代时)成为可能(例如 list.forEach(System.out::println))。但同样,阵列不享受这种待遇。 (我知道有一些解决方法)。
是否有技术原因导致 javac 无法增强以在 forEach 中接受数组,就像它在增强的 for 循环中接受数组一样?似乎不需要数组实现 Iterable 就可以生成代码。我是不是太天真了?
这对于语言的新手来说尤其重要,因为它们的语法很简单,所以很自然地使用数组。切换到列表并使用 Arrays.asList(1, 2, 3) 并不自然。
最佳答案
在 Java 语言和 JVM 中,数组有很多特殊情况。数组有一个 API,但它几乎不可见。就好像数组被声明为:
implements Cloneable, Serializable public final int length public T[] clone()在哪里 T是数组的组件类型但是,这些声明在任何地方的任何源代码中都不可见。见 JLS 4.10.3和 JLS 10.7解释。 Cloneable和 Serializable通过反射可见,并通过调用返回
Object[].class.getInterfaces()
也许令人惊讶的是,length字段和 clone()方法在反射中不可见。 length字段根本不是字段;使用它会变成一个特殊的 arraylength字节码。调用clone()导致实际的虚方法调用,但如果接收方是数组类型,则由 JVM 专门处理。
值得注意的是,数组类没有实现 Iterable界面。
在 Java SE 5 中添加增强型 for 循环(“for-each”)后,它支持右侧表达式的两种不同情况:Iterable或数组类型 ( JLS 14.14.2 )。原因是Iterable增强的for语句对实例和数组的处理完全不同。 JLS的那部分给出了完整的处理,但更简单地说,情况如下。
对于 Iterable<T> iterable , 代码
for (T t : iterable) {
<loop body>
}
是语法糖
for (Iterator<T> iterator = iterable.iterator(); iterator.hasNext(); ) {
t = iterator.next();
<loop body>
}
对于数组 T[] , 代码
for (T t : array) {
<loop body>
}
是语法糖
int len = array.length;
for (int i = 0; i < len; i++) {
t = array[i];
<loop body>
}
现在,为什么要这样做?数组当然可以实现Iterable ,因为它们已经实现了其他接口(interface)。编译器也可以合成 Iterator由数组支持的实现。 (这是有先例的。编译器已经合成了静态的 values() 和 valueOf() 方法,这些方法会自动添加到每个 enum 类中,如 JLS 8.9.3 中所述。)
但是数组是一个非常低级的结构,通过 int 访问数组值(value)预计是极其便宜的操作。从 0 运行循环索引是非常惯用的。到数组的长度,每次加一。数组上的增强型 for 循环正是这样做的。如果使用 Iterable 实现了数组上的增强 for 循环协议(protocol),我想大多数人会惊讶地发现循环数组涉及初始方法调用和内存分配(创建 Iterator ),然后是每个循环迭代的两个方法调用。
所以当默认方法被添加到 Iterable在 Java 8 中,这根本不影响数组。
正如其他人所指出的,如果您有一个数组 int , long , double ,或引用类型,可以使用 Arrays.stream() 之一将其转换为流来电。这提供了对 map() 的访问权限, filter() , forEach()等。
不过,如果 Java 语言和 JVM 中用于数组的特殊情况被 real 构造替换(同时修复一堆其他与数组相关的问题,例如糟糕的处理 2+ 维数组、2^31 长度限制等)。这是 John Rose 领导的“Arrays 2.0”调查的主题。请参阅 John 在 JVMLS 2012 上的演讲(video、slides)。与此讨论相关的想法包括为数组引入实际接口(interface),以允许库插入元素访问,以支持切片和复制等其他操作。
请注意,所有这些都是调查和 future 的工作。在撰写本文时 (2016-02-23),Java 路线图中没有任何关于这些数组增强功能的内容。
关于java - 在 Java 8 中,为什么没有给数组提供 Iterable 的 forEach 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35518471/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(