Java语法糖之foreach

语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢

了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用了。

这些语法糖虽然不会提供实质性的功能改进,但是它们或能提高性能、或能提升语法的严谨性、或能减少编码出错

的机会。

Java提供给了用户大量的语法糖,比如泛型、自动装箱、自动拆箱、foreach循环、变长参数、内部类、枚举

类、断言(assert)等。
package com.learn.foreach;

import java.util.ArrayList;
import java.util.List;

public class ForeachTest {

	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("s1");
		list.add("s2");
		
		for (String s : list) {
			System.out.println(s);
		}
	}
}
反编译出来的内容很多,看不懂也没关系,关键看到Iterator这个标志,其实在对有实现Iterable接口的对象采

用foreach语法糖的话,编译器会将这个for关键字转化为对目标的迭代器使用。

上面的代码会被转化为如下的代码:

package com.learn.foreach;

import java.util.ArrayList;
import java.util.List;

import com.learn.iterator.Iterator;

public class ForeachTest {
	
	/**
	 * 编译器会对没有显示构造函数的类添加一个默认的构造函数,
	 * 这个阶段是在语义分析阶段完成的
	 */
	public ForeachTest() {
		super();
	}

	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("s1");
		list.add("s2");
		
		for(Iterator it = (Iterator) list.iterator();it.hasNext();) {
			String s = (String)it.next();
			{
				System.out.println(s);
			}
		}
	}
}
注:如果要想使自己自定义的类可以采用foreach语法糖就必须实现Iterable接口。
java中的数组也可以采用foreach的语法糖,但是数组并没有实现Iterable接口呀。
package com.learn.foreach;

public class ForeachTest2 {
	
	public static void main(String[] args) {
		String arr[] = {"s1","s2"};
		for (String s : arr) {
			System.out.println(s);
		}
	}

}
数组的foreach语法糖并没有采用Iterable实现转换。真正的解析结果如下所示:

package com.learn.foreach;

public class ForeachTest2 {
	
	public ForeachTest2() {
		super();
	}
	
	public static void main(String[] args) {
		int arr[] = {1,2};
		int [] arr$ = arr;
		for(int len$ = arr$.length; i$=0; i$<len$; ++i$) {
			int i = arr$[i$];
			{
				System.out.println(i);
			}
		}
	}

}
可以看到对于数组而言,其实就是转换为普通的遍历而已;

关于foreach语法糖的信息就这样结束了嚒? 显然没有!

对于实现RandomAccess接口的集合比如ArrayList,应当使用最普通的for循环而不是foreach循环来遍历,所

以第一个例子中有欠妥之处。
首先看一下jdk1.7中对RandomAccess接口的定义:

java.util
Interface RandomAccess

All Known Implementing Classes:
ArrayList, AttributeList, CopyOnWriteArrayList, RoleList, RoleUnresolvedList, Stack,
Vector

public interface RandomAccess
Marker interface used by List implementations to indicate that they support fast (generally constant time) random access. The primary purpose of this interface is to allow generic algorithms to alter their behavior to provide good performance when applied to either random or sequential access lists.
The best algorithms for manipulating random access lists (such as ArrayList) can produce quadratic behavior when applied to sequential access lists (such as LinkedList). Generic list algorithms are encouraged to check whether the given list is an instanceof this interface before applying an algorithm that would provide poor performance if it were applied to a sequential access list, and to alter their behavior if necessary to guarantee acceptable performance.
It is recognized that the distinction between random and sequential access is often fuzzy. For example, some List implementations provide asymptotically linear access times if they get huge, but constant access times in practice. Such a List implementation should generally implement this interface. As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:
for (int i=0, n=list.size(); i < n; i++)
list.get(i);

runs faster than this loop:
for (Iterator i=list.iterator(); i.hasNext(); )
i.next();

This interface is a member of the Java Collections Framework.

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值