java for循环顺序的执行顺序和几种常用写法

本章节,我们介绍java里的循环,在开始本章节之前,先给大家提出一个问题,比如说,我让你用print显示出10条"Hello baby"的信息,你会怎么做呢? 从我们以前所学的知识来看,这很简单,只需要System.out.println("Hello baby");十次即可。但是我让你显示出100次甚至更多呢? 也许你说我是无理取闹,是的,这个问题本身并没有实际的意义,但是这样的问题实际上就是:多次执行相同或者有一定规律的操作。在这种时候,我们需要用到循环。只从语义来讲,循环就是do it again and again对吧?但是怎么来做呢?
& & java里有两种循环,for循环和while循环,本次,我们先来介绍for循环。
& & for循环里有两种,普通for循环和for each循环,后者是java后来加上去的,原本是没有的。先说普通for循环:
& & 普通for循环的格式是这样的:
& & for(初始化条件(一般为数据的初始化); 判断条件(一般与前面初始化的数据有关); 条件改变(一般改变那个数据))
& & {执行的操作}(如果执行的操作只有一条语句,花括号可以省略掉,但是建议初学者不要这么做,容易把自己弄糊涂。)
& & 那么,上面这个for循环是怎么执行的呢?&我们来写个小程序,来说明一下这个问题:
你看,我们打印出了10条Hello baby!对吧?但是到底发生了什么呢?下面我们详细解释一下,
for(int i = 0; i & 10; i ++)
& & & & System.out.println("Hello baby!");
i是一个整型数据,在for循环的最最开始,它被定义并初始化为0,然后判断它是否小于10,如果小于10,那么执行
for后面花括号里的操作,如果不小于10,直接退出循环。我们的i目前等于0,所以,执行了操作,打印出了一个"Hello baby!",然后呢? 然后程序将跳转回for后面的圆括号那行,但是,java将从右往左执行,就是说,先执行 & i ++,这个是i自加1的意思,于是,我们的i变成了1,然后判断,i & 10是否为真?为真,因为i现在等于1,既然为真,那就继续跳转进花括号进行操作,于是又打印出一条"Hello baby",然后再跳转到圆括号那里,i ++,i变成2,然后再打印出信息,知道i等于9之后,i++,这次变成了10,i & 10这次为false了,将不再进入花括号执行操作,而是跳出循环,我们这个程序,只有一个for循环,跳出此循环,程序就结束了。
& & 这个例子也许没什么实际的意义,那么我们这里来看看有点儿实际意义的。 著名的数学家高斯,在10岁那年,用较短的时间,轻松的算出了1+2+3+...+100 = 5050, 使得他的老师彪特奈尔异常激动,意识到自己发现了一个天才。我们现在知道,当年高斯的算法是第一个数加上最后一个数是101,第二个数加上倒数第二个也是101,一共有50对这样的加法,最后得到5050,那么如果我们用java的for循环来做呢? 我们在此用两种方法,一种是1+2+...+100,另一种就是模拟高斯的做法,程序代码如下:
你看,结果是相同的是吧,哎,如果当年有java,那轮得到高斯在那儿装啊? 就算用笨办法也比他做的快啊。可惜啊,当懒惰的Patrick Naughton在1990年12月大声抱怨C++的时候,距离高斯算出5050这个数字已经213年了。
& & 以上便是普通的for循环,一般来说,for循环经常控制某些操作的执行次数,所以,多数情况下,会对整形数据进行初始化和自加操作。但这不是绝对的,for循环可以很灵活的,比如下面的例子:
这个例子打印出Thinking in JAVA,但是每次都少打一个字母,这有些像"我顿时凌乱了, 顿时凌乱了,时凌乱了,凌乱了,乱了,了&, 对吧,这个小程序用到了String的基本操作,我们还没有涉及到。不过这没关系,我只是说,普通for循环的格式是死板的,但是使用for循环的人是灵活的。
& & 我们今天就说到这里吧,虽然我本来还想说说for each循环,但是那必然会涉及到数组的问题,而我们还没有说到数组,所以for each循环我们留到后面再说吧。
阅读(...) 评论()for循环三种写法
我的图书馆
for循环三种写法
第一种for循环 对于遍历数组,这个循环一般是采取这样的写法:   清单1:遍历数组的传统方式 Java代码 /*&建立一个数组&*/&& int[]&integers&=&{1,&2,&3,&4}; && /*&开始遍历&*/&& for&(int&j&=&0;&j&&&integers.&j++)&{ && int&i&=&integers[j]; && System.out.println(i); && }&&  而对于遍历Collection对象,这个循环则通常是采用这样的形式:   清单2:遍历Collection对象的传统方式 Java代码 /*&建立一个Collection&*/&& String[]&strings&=&{"A",&"B",&"C",&"D"}; && Collection&stringList&=&java.util.Arrays.asList(strings); && /*&开始遍历&*/&& for&(Iterator&itr&=&stringList.iterator();&itr.hasNext();)&{ && Object&str&=&itr.next(); && System.out.println(str); && }&&  而在Java语言的最新版本——J2SE 1.5中,引入了另一种形式的for循环。借助这种形式的for循环,现在可以用一种更简单地方式来进行遍历的工作。 第二种for循环   不严格的说,Java的第二种for循环基本是这样的格式:   for (循环变量类型 循环变量名称 : 要被遍历的对象) 循环体   借助这种语法,遍历一个数组的操作就可以采取这样的写法:   清单3:遍历数组的简单方式 Java代码 /*&建立一个数组&*/&& int[]&integers&=&{1,&2,&3,&4}; && /*&开始遍历&*/&& for&(int&i&:&integers)&{ && System.out.println(i);/*&依次输出“1”、“2”、“3”、“4”&*/&& }&&  这里所用的for循环,会在编译期间被看成是这样的形式:   清单4:遍历数组的简单方式的等价代码 Java代码 /*&建立一个数组&*/&& int[]&integers&=&{1,&2,&3,&4}; && /*&开始遍历&*/&& for&(int&变量名甲&=&0;&变量名甲&&&integers.&变量名甲++)&{ && System.out.println(变量名甲);/*&依次输出“1”、“2”、“3”、“4”&*/&& }&&  这里的“变量名甲”是一个由编译器自动生成的不会造成混乱的名字。   而遍历一个Collection的操作也就可以采用这样的写法:   清单5:遍历Collection的简单方式 Java代码 /*&建立一个Collection&*/&& String[]&strings&=&{"A",&"B",&"C",&"D"}; && Collection&list&=&java.util.Arrays.asList(strings); && /*&开始遍历&*/&& for&(Object&str&:&list)&{ && System.out.println(str);/*&依次输出“A”、“B”、“C”、“D”&*/&& }&&  这里所用的for循环,则会在编译期间被看成是这样的形式:   清单6:遍历Collection的简单方式的等价代码 Java代码 /*&建立一个Collection&*/&& String[]&strings&=&{"A",&"B",&"C",&"D"}; && Collection&stringList&=&java.util.Arrays.asList(strings); && /*&开始遍历&*/&& for&(Iterator&变量名乙&=&list.iterator();&变量名乙.hasNext();)&{ && System.out.println(变量名乙.next());/*&依次输出“A”、“B”、“C”、“D”&*/&& }&&&  这里的“变量名乙”也是一个由编译器自动生成的不会造成混乱的名字。   因为在编译期间,J2SE 1.5的编译器会把这种形式的for循环,看成是对应的传统形式,所以不必担心出现性能方面的问题。
喜欢该文的人也喜欢比如定义一个数组int a[]={1, 2, 3, 4},下面我们罗列一下遍历这个数组的方法
这也是最常用的方法,不多做解释。代码如下
int a[] = {1, 2, 3, 4};
for(int i=0; i&a. i++){
System.out.println(a[i]);
先上代码:
int a[] = {1, 2, 3, 4};
for(int i:a){
System.out.println(i);
for(int i:a)解释是:先设置一个与a数组里的元素相同的变量,这个变量先等于a数组的第一个元素,然后进入循环体,第二次循环就等于a数组的第二个元素,进入循环体,以此类推。
3&Collection&for(Iterator i = intList.iterator();i.hasNext();)
int a[] = {1, 2, 3, 4};
Collection intList = java.util.Arrays.asList(a);
for(Iterator i = intList.iterator();i.hasNext();){
Object j = i.next();
System.out.println(j);
java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。其中Iterator就是这个接口中的一种方法,学java的人都熟悉,叫迭代器,i.hasNext()方法返回值是boolean类型,若为true则表示迭代器下一个有值,否则表示迭代完成;i.next()返回值是一个object类型,表示取出迭代器下一个值并赋值给“=”之前。所以就能够给for循环提供循环的条件了。
阅读(...) 评论()java的for循环 | 基于实例代码分步讲解 一站式学习Java | how2j.cn
for循环,和while一样,只是表达方式不一样
本视频是解读性视频,所以希望您已经看过了本知识点的内容,并且编写了相应的代码之后,带着疑问来观看,这样收获才多。 不建议一开始就观看视频
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器
如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)
走神了?退回10秒
比较for和while
public class HelloWorld {
public static void main(String[] args) {
//使用while打印0到4
int i = 0;
while(i&5){
System.out.println(&while循环输出的&+i);
//使用for打印0到4
for (int j = 0; j & 5; j++) {
System.out.println(&for
循环输出的&+j);
public class HelloWorld {
public static void main(String[] args) {
//使用while打印0到4
int i = 0;
while(i&5){
System.out.println(&while循环输出的&+i);
//使用for打印0到4
for (int j = 0; j & 5; j++) {
System.out.println(&for
循环输出的&+j);
&姿势不对,事倍功半!
天朝有一个乞丐姓洪,去天桥要钱第一天要了1块钱第二天要了2块钱第三天要了4块钱第四天要了8块钱以此类推问题: 洪乞丐干10天,收入是多少?
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
本视频是解读性视频,所以希望您已经看过了本答案的内容,带着疑问来观看,这样收获才多。 不建议一开始就观看视频
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器
如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)
走神了?退回10秒
public class HelloWorld {
public static void main(String[] args) {
int moneyEachDay = 0;
int day = 10;
int sum=0;
for (int i = 1; i &= i++) {
if(0==moneyEachDay)
moneyEachDay = 1;
moneyEachDay *= 2;
sum+=moneyEachD
System.out.println(i + & 天之后,洪帮主手中的钱总数是: & + sum );
public class HelloWorld {
public static void main(String[] args) {
int moneyEachDay = 0;
int day = 10;
int sum=0;
for (int i = 1; i &= i++) {
if(0==moneyEachDay)
moneyEachDay = 1;
moneyEachDay *= 2;
sum+=moneyEachD
System.out.println(i + & 天之后,洪帮主手中的钱总数是: & + sum );
把你的代码复制到下面区域。 如果在线比较不好用,请使用客户端比较软件:
代码高亮插件双击即可选中,不过部分同学反应,通过代码高亮插件复制的代码无法在IDEA里正常显示,这里提供TEXTAREA的方式,方便复制,谢谢
根据练习目标尽量自己实现代码效果,期间会碰到疑问,难题,和自己不懂的地方,这些都是必要的过程
完成过程中,碰到无法解决的问题,带着疑问,查看答案,分析答案的解决思路
依然有不明白的地方,点开视频讲解,带着疑问,听视频讲解有问题的部分
理解后,再从头做一遍,把有疑问的地方都捋清楚
最后再总结一遍,总结思路,总结解决办法,以后遇到类似的问题,怎么处理
把这时的想法,思路,研究都记录下来,等全部学完了,再回过头来巩固和理解,学习效果就会很好,知识点掌握得也牢固.
HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
把苹果咬哭
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
小可的java
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
huangcz815
答案时间:
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
飞翔的企鹅
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
一只勤劳的小码农
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
tequilasu2010
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
wqh0109663
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
dfgefgavcwf
答案时间:
答案时间:
chenjimalayou
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
Reol_Frank
答案时间:
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
iloveyou无望
答案时间:
VincentCHEN
答案时间:
答案时间:
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
墨轩_kernel
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
我是小码农
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
scotthwang
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
爱刷屏的萝卜头
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
该用户已注销
答案时间:
答案时间:
奔跑的菊花茶
答案时间:
江南桥下客
答案时间:
答案时间:
答案时间:
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
提问之前请
喜迎暑假,一半时间世界杯,一半时间学习提高,全场五折,优惠码:WORLDCUP
可用于全站通
有效期6.25-6.27java for循环的执行顺序和几种常用写法
算是温习吧。问题比较基础,但是也比较重要。(虽然是C,但是很经典)
for循环可以说在每个程序中都少不了的,语句头包括三个部分:初始化,判读条件,一个表达式。
但是这三个部分的执行顺序是什么,这是我们所关心的,也是本文所要讨论的。
下面先看一段简单的代码。
代码很简单,可是打印结果呢?
有的朋友可能会想当然的认为,
打印结果是1.
可是,真的是1吗?
复制到编译器上跑跑,奇迹般的发现,其实是2.
下面就分析下这简单代码。
第一步:初始化定义,x = 0, a = 0;
第二步:a小于1, x 的非为1,符合循环条件
第三步:x++后x自增为1.
第四步:进入循环体,a++,a自增为1.
第五步:执行循环语句头中的a++,a自增为2.
第六步:执行循环语句头的判读条件,a=2&1,故不满足,不执行循环语句。
第七步:打印a的值为2.
怎么样,现在豁然开朗了吧。(如果还是不懂...那就抱歉了。)
从这个例子,我们可以得出如下结论:
执行顺序是:初始化--判断--函数体——然后for循环的第3句--判断——函数体---for循环的第三句--判断……
下面解答几点疑惑:
1、第一次例如初始化i=0,是否还执行后面的i++或++i?
第一次先初始化,然后判断,i++就不执行了
2、第一次完了以后,初始化这句就不用了,是先执行i++还是限制性判断语句呢?
3、现在知道是先执行i++,再执行判断语句,i++不是后++吗,例如i为1,那i++后执行判断语句,i是几呢?
4、好像i++和++i在for()里时结果都一样。
都一样,for语句头的执行顺序决定了这两个写法都一样,都是i++或这++i这两句执行完了再进行判断,此时(两种情况)i已经加1了。
分析了这么多,相信大家也都懂了。
留个经典的例子,让大家自己去分析吧。
打印结果:
如果不懂的,可以参照下面这个对上述例子逐句打印的例子,应该会有助于理解。
打印结果:
执行判断条件,i=0,j=10
0,10 执行for循环体中的最后一句,i=0,j=10
执行for()中的第三个语句,i=1,j=9
执行判断条件,i=1,j=9
执行for循环体中的最后一句,i=1,j=10
执行for()中的第三个语句,i=2,j=9
执行判断条件,i=2,j=9
执行for循环体中的最后一句,i=2,j=10
执行for()中的第三个语句,i=3,j=9
执行判断条件,i=3,j=9
执行for循环体中的最后一句,i=3,j=10
执行for()中的第三个语句,i=4,j=9
执行判断条件,i=4,j=9
执行for循环体中的最后一句,i=4,j=10
执行for()中的第三个语句,i=5,j=9
执行判断条件,i=5,j=9
执行for循环体中的最后一句,i=5,j=10
执行for()中的第三个语句,i=6,j=9
执行判断条件,i=6,j=9
执行for循环体中的最后一句,i=6,j=10
执行for()中的第三个语句,i=7,j=9
执行判断条件,i=7,j=9
执行for循环体中的最后一句,i=7,j=10
执行for()中的第三个语句,i=8,j=9
执行判断条件,i=8,j=9
执行for循环体中的最后一句,i=8,j=10
执行for()中的第三个语句,i=9,j=9
执行判断条件,i=9,j=9
下面讲述for循环在遍历过程中的使用
J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环,可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式,说明如何自行定义能被这样遍历的类,并解释和这一机制的一些常见问题。
在Java程序中,要“逐一处理”――或者说,“遍历”――某一个数组或Collection中的元素的时候,一般会使用一个for循环来实现(当然,用其它种类的循环也不是不可以,只是不知道是因为for这个词的长度比较短,还是因为for这个词的含义和这种操作比较配,在这种时候for循环比其它循环常用得多)。
对于遍历数组,这个循环一般是采取这样的写法:
清单1:遍历数组的传统方式
/* 建立一个数组 */
int[] integers = {1, 2, 3, 4};
/* 开始遍历 */
for (int j = 0; j&integers. j++){
int i = integers[j];
System.out.println(i);
而对于遍历Collection对象,这个循环则通常是采用这样的形式:
清单2:遍历Collection对象的传统方式
/* 建立一个Collection */
String[] strings = {"A", "B", "C", "D"};
Collection stringList = java.util.Arrays.asList(strings);
/* 开始遍历 */
for (Iterator itr = stringList.iterator(); itr.hasNext();) {
Object str = itr.next();
System.out.println(str);
而在Java语言的最新版本――J2SE 1.5中,引入了另一种形式的for循环。借助这种形式的for循环,现在可以用一种更简单地方式来进行遍历的工作。
1. 第二种for循环
不严格的说,Java的第二种for循环基本是这样的格式:
for (循环变量类型 循环变量名称 : 要被遍历的对象) 循环体
借助这种语法,遍历一个数组的操作就可以采取这样的写法:
清单3:遍历数组的简单方式
/* 建立一个数组 */
int[] integers = {1, 2, 3, 4};
/* 开始遍历 */
for (int i : integers) {
System.out.println(i);/* 依次输出“1”、“2”、“3”、“4” */
这里所用的for循环,会在编译期间被看成是这样的形式:
清单4:遍历数组的简单方式的等价代码
/* 建立一个数组 */
int[] integers = {1, 2, 3, 4};
/* 开始遍历 */
for (int 变量名甲 = 0; 变量名甲&integers. 变量名甲++)="" {
System.out.println(integers[变量名甲]);/* 依次输出“1”、“2”、“3”、“4” */
这里的“变量名甲”是一个由编译器自动生成的不会造成混乱的名字。
而遍历一个Collection的操作也就可以采用这样的写法:
清单5:遍历Collection的简单方式
/* 建立一个Collection */
String[] strings = {"A", "B", "C", "D"};
Collection list = java.util.Arrays.asList(strings);
/* 开始遍历 */
for (Object str : list) {
System.out.println(str);/* 依次输出“A”、“B”、“C”、“D” */
这里所用的for循环,则会在编译期间被看成是这样的形式:
清单6:遍历Collection的简单方式的等价代码
/* 建立一个Collection */
String[] strings = {"A", "B", "C", "D"};
Collection stringList = java.util.Arrays.asList(strings);
/* 开始遍历 */
for (Iterator 变量名乙 = list.iterator(); 变量名乙.hasNext();) {
Object str = 变量名乙.next();
System.out.println(str);/* 依次输出“A”、“B”、“C”、“D” */
这里的“变量名乙”也是一个由编译器自动生成的不会造成混乱的名字。
因为在编译期间,J2SE 1.5的编译器会把这种形式的for循环,看成是对应的传统形式,所以不必担心出现性能方面的问题。
不用“foreach”和“in”的原因
Java采用“for”(而不是意义更明确的“foreach”)来引导这种一般被叫做“for-each循环”的循环,并使用“:”(而不是意义更明确的“in”)来分割循环变量名称和要被遍历的对象。这样作的主要原因,是为了避免因为引入新的关键字,造成兼容性方面的问题――在Java语言中,不允许把关键字当作变量名来使用,虽然使用“foreach”这名字的情况并不是非常多,但是“in”却是一个经常用来表示输入流的名字(例如java.lang.System类里,就有一个名字叫做“in”的static属性,表示“标准输入流”)。
的确可以通过巧妙的设计语法,让关键字只在特定的上下文中有特殊的含义,来允许它们也作为普通的标识符来使用。不过这种会使语法变复杂的策略,并没有得到广泛的采用。
“for-each循环”的悠久历史
“for-each循环”并不是一个最近才出现的控制结构。在1979正式发布的Bourne shell(第一个成熟的UNIX命令解释器)里就已经包含了这种控制结构(循环用“for”和“in”来引导,循环体则用“do”和“done”来标识)。
2. 防止在循环体里修改循环变量
在默认情况下,编译器是允许在第二种for循环的循环体里,对循环变量重新赋值的。不过,因为这种做法对循环体外面的情况丝毫没有影响,又容易造成理解代码时的困难,所以一般并不推荐使用。
Java提供了一种机制,可以在编译期间就把这样的操作封杀。具体的方法,是在循环变量类型前面加上一个“final”修饰符。这样一来,在循环体里对循环变量进行赋值,就会导致一个编译错误。借助这一机制,就可以有效的杜绝有意或无意的进行“在循环体里修改循环变量”的操作了。
清单7:禁止重新赋值
int[] integers = {1, 2, 3, 4};
for (final int i : integers) {
i = i / 2; /* 编译时出错 */
注意,这只是禁止了对循环变量进行重新赋值。给循环变量的属性赋值,或者调用能让循环变量的内容变化的方法,是不被禁止的。
清单8:允许修改状态
Random[] randoms = new Random[]{new Random(1), new Random(2), new Random(3)};
for (final Random r : randoms) {
r.setSeed(4);/* 将所有Random对象设成使用相同的种子 */
System.out.println(r.nextLong());/* 种子相同,第一个结果也相同 */
3. 类型相容问题
为了保证循环变量能在每次循环开始的时候,都被安全的赋值,J2SE 1.5对循环变量的类型有一定的限制。这些限制之下,循环变量的类型可以有这样一些选择:
循环变量的类型可以和要被遍历的对象中的元素的类型相同。例如,用int型的循环变量来遍历一个int[]型的数组,用Object型的循环变量来遍历一个Collection等。
清单9:使用和要被遍历的数组中的元素相同类型的循环变量
int[] integers = {1, 2, 3, 4};
for (int i : integers) {
System.out.println(i);/* 依次输出“1”、“2”、“3”、“4” */
清单10:使用和要被遍历的Collection中的元素相同类型的循环变量
Collection& String& strings = new ArrayList& String&();
strings.add("A");
strings.add("B");
strings.add("C");
strings.add("D");
for (String str : integers) {
System.out.println(str);/* 依次输出“A”、“B”、“C”、“D” */
循环变量的类型可以是要被遍历的对象中的元素的上级类型。例如,用int型的循环变量来遍历一个byte[]型的数组,用Object型的循环变量来遍历一个Collection& String&(全部元素都是String的Collection)等。
清单11:使用要被遍历的对象中的元素的上级类型的循环变量
String[] strings = {"A", "B", "C", "D"};
Collection& String& list = java.util.Arrays.asList(strings);
for (Object str : list) {
System.out.println(str);/* 依次输出“A”、“B”、“C”、“D” */
循环变量的类型可以和要被遍历的对象中的元素的类型之间存在能自动转换的关系。J2SE 1.5中包含了“Autoboxing/Auto-Unboxing”的机制,允许编译器在必要的时候,自动在基本类型和它们的包裹类(Wrapper Classes)之间进行转换。因此,用Integer型的循环变量来遍历一个int[]型的数组,或者用byte型的循环变量来遍历一个Collection& Byte&,也是可行的。
清单12:使用能和要被遍历的对象中的元素的类型自动转换的类型的循环变量
int[] integers = {1, 2, 3, 4};
for (Integer i : integers) {
System.out.println(i);/* 依次输出“1”、“2”、“3”、“4” */
注意,这里说的“元素的类型”,是由要被遍历的对象的决定的――如果它是一个Object[]型的数组,那么元素的类型就是Object,即使里面装的都是String对象也是如此。
可以限定元素类型的Collection
截至到J2SE 1.4为止,始终无法在Java程序里限定Collection中所能保存的对象的类型――它们全部被看成是最一般的Object对象。一直到J2SE 1.5中,引入了“泛型(Generics)”机制之后,这个问题才得到了解决。现在可以用Collection& T&来表示全部元素类型都是T的Collection。
没有更多推荐了,

我要回帖

更多关于 java增强for循环 的文章

 

随机推荐