黑马程序员技术交流社区

标题: ArrayList for 循环问题 [打印本页]

作者: ⑷嚸V恱    时间: 2013-8-19 19:56
标题: ArrayList for 循环问题
本帖最后由 ⑷嚸V恱 于 2013-8-20 13:50 编辑

各位大虾  
        ArrayList a=new ArrayList<String>();
        a.add("aa");
        for(String s:a){
            System.out.println(s);
        }
   这样 用for 循环为什么不行
for 循环集合只能是这种形式吗?
       ArrayList a=new ArrayList<String>();
        a.add("aa");
        /*for(String s:a){
            System.out.println(s);
        }*/
        for(int i=0;i<a.size();i++){
            
            System.out.println(a.get(i));
        }


作者: 白堇翎    时间: 2013-8-19 20:27
高级for循环是遍历数组的,不能遍历集合
作者: sunriselzz    时间: 2013-8-19 21:21
楼上的,好像回复说的不确切吧,高级for循环可以遍历数组的,也能遍历集合!
同时提问者的ArrayList  a = new ArrayList<String>(); 的左路ArrayList的泛型少写了<String>
以至于在编译的时候,高级for (String s : a)a会编译报错!
提示: Type mismatch: cannot convert from element type Object to String
改正后的代码是这两种遍历都是可以的
  1. package cn.java.technology;

  2. import java.util.ArrayList;

  3. public class Test {
  4.         /**
  5.          * @param args
  6.          */
  7.         public static void main(String[] args) {
  8.                 // TODO Auto-generated method stub
  9.                 ArrayList<String> a = new ArrayList<String>();
  10.                 a.add("aa");
  11.                 for (String s : a) {
  12.                         System.out.println(s);
  13.                 }
  14.                 // 这样 用for 循环为什么不行
  15.                 // for 循环集合只能是这种形式吗?
  16.                 for (int i = 0; i < a.size(); i++) {
  17.                         System.out.println(a.get(i));
  18.                 }

  19.         }

  20. }
复制代码
关于参数化类型的几点说明:
        1、参数化类型与原始类型的兼容性
           第一、参数化类型可引用一个原始类型的对象,编译只是报警告
           如:Collection<String> coll = new Date();
           第二、原始类型可引用一个参数化类型的对象,编译报告警告
           如:Collection coll = new Vector<String>();
           原来的方法接受一个集合参数,新类型也要能传进去。
        2、参数的类型不考虑类型参数的继承关系:
           ector<String> v = new Vector<Objec>();//错误的
           不写Object没错,写了就是明知故犯
           Vector<Objec> v = new Vector<String>();//错误的
        3、在创建数组实例时,数组的元素不能使用参数化的类型
           如:Vector<Integer> v[] = newVector<Integer>[10];//错误的


作者: ⑷嚸V恱    时间: 2013-8-19 21:35
sunriselzz 发表于 2013-8-19 21:21
楼上的,好像回复说的不确切吧,高级for循环可以遍历数组的,也能遍历集合!
同时提问者的ArrayList  a = new A ...

ArrayList 不用泛型修饰,for each 循环ArrayList 编译出错 ,原因是什么?你刚才说的那几点 很好 ,能帮我解释一下这个问题吗?


作者: 白堇翎    时间: 2013-8-19 22:00
本帖最后由 白堇翎 于 2013-8-19 22:12 编辑
sunriselzz 发表于 2013-8-19 21:21
楼上的,好像回复说的不确切吧,高级for循环可以遍历数组的,也能遍历集合!
同时提问者的ArrayList  a = new A ...

好吧, 我这样说总没问题了吧..
高级for循环不能遍历未指定泛型,泛型为不确定数据类型,通配符 的集合当然 你在用Object的话..也是可以的



作者: sunriselzz    时间: 2013-8-19 22:09
原始类型可引用一个参数化类型的对象,编译报告警告
这个警告: ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized
这个警告的意思是右边是参数化的类型ArrayList,而左边是未参数化的
如果非要是: ArrayList a=new ArrayList<String>();
那么高级for里编译会提示: Type mismatch: cannot convert from element type Object to String的错误
而Java在把类文件编译完成.class后是去泛型的,也称为泛型的擦除
而在运行时,他又会重新给它加回泛型,但是在左边由于没有指定类型,那么编译器就会把它当作存储的是Object的类型,而存储Object元素的集合a是不能直接赋值给String 的s的!
注: 这仅是本人学习的观点,可能并不准确,仅供参考!
作者: 肥猫    时间: 2013-8-19 22:10
白堇翎 发表于 2013-8-19 20:27
高级for循环是遍历数组的,不能遍历集合

FOREACH不能遍历集合?你在逗我?你叫曾四豆?

作者: 肥猫    时间: 2013-8-19 22:12
本帖最后由 肥猫 于 2013-8-19 22:15 编辑

楼主左边没定义泛型,在将对象存入集合时由于集合的擦除操作导致你遍历集合的时候无法确定是String类型的,当然遍历失败,
  1. public class A{
  2.      public static void main(String[] args){
  3.             ArrayList<String> al = new ArrayList<>();
  4.             al.add("a");
  5.             al.add("b");
  6.             al.add("c");
  7.             al.add("d");
  8.             for (String str1 : al) {
  9.                  System.out.println(str1);
  10.                 }
  11.             }
  12.       }
复制代码

作者: 刘张朋    时间: 2013-8-19 22:22
本帖最后由 刘张朋 于 2013-8-19 22:30 编辑

呵呵,原因很简单,你的集合a里面放的是Object,你遍历的时候把他当String肯定不行了,
你要不在定义a时加String泛型,要不在增强for里面把遍历得到的改成Object

增强for可以遍历数组跟单列集合,如Map结合不能直接遍历,但是可以转成Set集合后遍历
作者: 秦大忠    时间: 2013-8-20 11:57
在JDK5.0以后,为了方便对数组和集合中的元素进行迭代处理而引入的一种增强for循环,这样更更容易理解并且紧凑,说以说JDK5.0以后提倡尽量采用这种for循环
作者: 秦大忠    时间: 2013-8-20 11:58
在JDK5.0以后,为了方便对数组和集合中的元素进行迭代处理而引入的一种增强for循环,这样更更容易理解并且紧凑,说以说JDK5.0以后提倡尽量采用这种for循环,功能是一样的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2