java 数组 c foreach_在Java 8中,为什么Arrays没有给出forEach的Iterable方法?

Java语言和数组的JVM有一些特殊情况。数组有一个API,但几乎看不到。就好像数组被声明为具有:

>实现可克隆,可序列化

> public final int length

> public T [] clone()其中T是数组的组件类型

但是,这些声明在任何地方的任何源代码中都不可见。有关说明,请参见JLS 4.10.3和JLS 10.7。可克隆和可序列化通过反射可见,并通过调用返回

Object[].class.getInterfaces()

也许令人惊讶的是,长度字段和clone()方法是不可见的。长度字段根本不是一个字段;使用它变成一个特殊的数组长度字节码。对clone()的调用会导致实际的虚拟方法调用,但是如果接收器是数组类型,则由JVM特别处理。

值得注意的是,数组类不实现Iterable接口。

当在Java SE 5中添加了增强型for循环(“for-each”)时,它支持右侧表达式的两种不同的情况:一个Iterable或一个数组类型(JLS 14.14.2)。原因是可以通过enhanced-for语句完全不同地处理Iterable实例和数组。 JLS的这一部分给予了充分的对待,但更简单地说,情况如下。

对于可迭代的< T>可迭代的代码

for (T t : iterable) {

}

是句法糖

for (Iterator iterator = iterable.iterator(); iterator.hasNext(); ) {

t = iterator.next();

}

对于数组T [],代码

for (T t : array) {

}

是句法糖

for (int i = 0; i < array.length; i++) {

t = array[i];

}

现在为什么这样做呢?数组可以实现Iterable,因为它们已经实现了其他接口。编译器也可以合成由数组支持的迭代器实现。 (这里有先例,编译器已经合成了自动添加到每个枚举类的静态值()和valueOf()方法,如0703所述)

但是数组是一个非常低级别的构造,并且通过int值访问数组预计是非常便宜的操作。将循环索引从0运行到数组的长度是非常惯用的,每次递增1。阵列上的enhanced-for循环正好是这样。如果使用Iterable协议实现了对数组的增强型循环,我认为大多数人会惊讶地发现,循环遍历数组涉及初始方法调用和内存分配(创建Iterator),然后是两个方法调用每循环迭代。

所以当Java 8中添加了默认方法时,这并不影响数组。

正如其他人所说,如果你有一个int,long,double或者引用类型的数组,可以使用其中一个Arrays.stream()调用把它变成一个流。这提供了对map(),filter(),forEach()等的访问。

但是,如果Java语言中的特殊情况和数组的JVM被真正的构造所取代(同时修复了一系列与数组相关的其他问题,例如二维数组的不良处理,那么2 ^ 31长度限制等)。这是由“约翰·罗斯”领衔的“Arrays 2.0”调查的主题。见约翰在JVMLS 2012(video,slides)的演讲。与此讨论相关的想法包括引入数组的实际接口,以允许库插入元素访问,以支持诸如切片和复制等附加操作。

注意所有这一切都是调查和未来工作。在撰写本文时,这些数组增强功能在Java路线图中都没有提供任何版本(2016-02-23)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值