A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© —__ 中级黑马   /  2012-5-3 17:37  /  3371 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

import java.util.*;
class  ForEachDemo
{
        public static void main(String[] args)
        {
                ArrayList<String >al =new ArrayList<String>();
                al.add("abc1");
                al.add("abc2");
                al.add("abc3");

                Iterator<String> it = al.iterator();

                while (it.hasNext())
                {
                        System.out.println(it.next());
                }

        }
}
请看上面代码
共有两个问题。
1.按照上面的代码 我得出一个结论 it = al.ierator();
于是呢 我将 while(it.hasNext()) 写成了 while(al.iterator().hasNext()) 编译可以通过,但是一直循环打印"abc1" 问其原因是什么?


那么有没有什么办法 将 Iterator<String> it = al.iterator(); 这句代码合并到循环里面,也就是不写这句代码直接在循环中用代码替代。


2.这个实例是用来演示高级(增强)for循环的 而for循环的写法是

for (变量名:被遍历的集合或数组)
随后上面的代码简写成了
import java.util.*;
class  ForEachDemo
{
        public static void main(String[] args)
        {
                ArrayList<String >al =new ArrayList<String>();
                al.add("abc1");
                al.add("abc2");
                al.add("abc3");

                for(String s : al)
                {
                        System.out.println(s);
                }

        }
}
那么 问题2 就是 s : al 中的":"  冒号 相当与什么代码,能不能用最上面的代码帮我说明一下,如果不能那么针对这个冒号能不能写个代码让我弄明白冒号到底是什么意思?
另s 除了打印以外还有其他什么作用?

7 个回复

倒序浏览
(1)如果将 while(it.hasNext()) 写成了 while(al.iterator().hasNext())
那么每次循环又重新执行了 it = al.iterator();
其实就是以下程序
public class ForEachDemo {
public static void main(String[] args)
    {
            ArrayList<String >al =new ArrayList<String>();
            al.add("abc1");
            al.add("abc2");
            al.add("abc3");
            Iterator<String> it = al.iterator();
            while (it.hasNext())
            {
                    System.out.println(it.next());
                    it = al.iterator();
            }
    }
}
结果一直循环打印"abc1"
(2)既然foreach 用于遍历实现Iterable<E>接口的对象,必然内部使用了上面使用迭代器的代码," : " 就是一种语法规定,s 就是每一个String对象,可以使用String提供的每一个方法。
回复 使用道具 举报
1:
while(al.iterator().hasNext())表示你每次循环都执行了一次Iterator<String> it = al.iterator();再while (it.hasNext()),就以你的代码为例子:
import java.util.*;
class  ForEachDemo
{
        public static void main(String[] args)
        {
                ArrayList<String > al;   
                for(int i=1 ; i<=3 ; i++){
                     al =new ArrayList<String>();
                     al.add("abc"+i);
                }
        }
}
就像这样子,你加的只有一条,而不是3条。迭代应该是没有办法合并到循环内的。

2:第二个问题中的for相当于foreach,是jdk5.0版本之后才具有的特性吧,看这个比较比较:
for( int i=0 , i<al.size() ; i++){
        String s = al.get(i);//冒号应该就是一步的意思
        System.out.println(s);
}
回复 使用道具 举报
s是你从集合中得到的内容,你不是要打印它吗?还有什么作用。。
回复 使用道具 举报
for(Iterator<String> it = al.iterator() ; it.hasNext()) ; ){
        System.out.println(it.next());
}
回复 使用道具 举报
al.iterator()的作用是生成迭代器,而且,每运行一次这个方法,就生成一个迭代器,如果将
这句代码写在while内部,那么每次循环都会生成一个新的迭代器,每个迭代器的第一个元素
肯定是“abc1",所以一直循环打印相同的内容。

如果非要将迭代器写入循环,我觉得改为for循环是可以的:
for(Iterator it=al.iterator(); it.hasNext();){}(注意,自增部分可以省略)

至于怎样解释这个冒号,恕无能为力,这是java定义的,就像你不能解释为什么三元运算符
中会用到冒号和问号一样。java的规定,就不要问为什么了。
s代表的是al集合中的任一String类型的变量,可以实现对集合中变量的操作,有时可以看做
一般for循环。高级for循环和一般for循环的区别在于:一般for循环可以对角标进行操作,而
高级for循环是无法实现角标操作的。正如毕老师所说:凡是简便的,都有其弊端。
希望能讲解清楚。
回复 使用道具 举报
解答
1:while(it.hasNext()) 写成了 while(al.iterator().hasNext())  这两句代码是很不同的,第一句,你在开始时(相当于初始化) 对象it 获得al 的迭代器, 那么当你调用it.hasNext()的时候,它会判断有无下一个,如有则移动到下一个,若无当然退出循环了,
而第二句代码就完全不同意思,你al.iterator.hasNext() 相当于每次判断前都获取al的迭代器,就相当于每次判断,它都会去判断有没有第一个,显然你的里面有三个串,那么必然无限循环打印第一个了。
2:对于那个冒号,就是讲al中的元素按顺序赋给s ,所以对于LInkedList 这种获取元素必须由前向后寻找,建议使用增强for循环。
查看增强for循环,你会发现,他也是有Iterator实现,本质上并没有太多的不同,但是增强for 缺点要比直接使用Iterator明显,比如你这种for循环里面无法动态删增,对吧,
也不能获取元素的下标等,
对于那个s对象,能做的就得看你ArrayList中存的对象类型了,现在的s就是从里面取出对象的引用地址,所以你存储的对象有啥功能,这边当然也全部能用咯
顺便提一点 普通的for(int i = 0;i < al.size(); i++){
          String s = al.get(i);
//程序段。。
}
要比增强for循环快很多的
有疑问继续交流噢
回复 使用道具 举报
while(al.iterator().hasNext()) 在while循环中创建迭代器相当于每次循环都要创建一个新的迭代器,所以每次打印出的都是集合中的第一个值“abc1”了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马