黑马程序员技术交流社区

标题: 求增强for循环原理 [打印本页]

作者: 追逐    时间: 2014-3-24 15:53
标题: 求增强for循环原理
听了毕老师的增强for循环。感觉有点模糊。不是很明白。希望各位前辈帮帮忙。给一些文字版或者带代码的解析。

作者: 菜小徐    时间: 2014-3-24 15:57
本帖最后由 菜小徐 于 2014-3-24 16:07 编辑

增强for循环:
foreach语句,foreach简化了迭代器。
格式:// 增强for循环括号里写两个参数,第一个是声明一个变量,第二个就是需要迭代的容器
  1. for( 元素类型 变量名 : Collection集合 & 数组 ) {

  2. }
复制代码

高级for循环和传统for循环的区别:
    高级for循环在使用时,必须要明确被遍历的目标。这个目标,可以是Collection集合或者数组,如果遍历Collection集合,在遍历过程中还需要对元素进行操作,比如删除,
需要使用迭代器。
    如果遍历数组,还需要对数组元素进行操作,建议用传统for循环因为可以定义角标通过角标操作元素。如果只为遍历获取,可以简化成高级for循环,它的出现为了简化书写。
高级for循环可以遍历map集合吗?不可以。但是可以将map转成set后再使用foreach语句。
1)、作用:对存储对象的容器进行迭代: 数组  collection   map 2)、增强for循环迭代数组:
  1. String [] arr = {"a", "b", "c"};//数组的静态定义方式,只试用于数组首次定义的时候
  2. for(String s : arr) {
  3. System.out.println(s);
  4. }
复制代码

3)、单列集合 Collection:
  1. List list = new ArrayList();
  2. list.add("aaa");
  3. // 增强for循环, 没有使用泛型的集合能不能使用增强for循环迭代?能
  4. for(Object obj : list) {
  5. String s = (String) obj;
  6. System.out.println(s);
  7. }
复制代码

4)、双列集合 Map:
  1. Map map = new HashMap();
  2. map.put("a", "aaa");
  3. // 传统方式:必须掌握这种方式
  4. Set entrys = map.entrySet(); // 1.获得所有的键值对Entry对象
  5. iter = entrys.iterator(); // 2.迭代出所有的entry
  6. while(iter.hasNext()) {
  7. Map.Entry entry = (Entry) iter.next();
  8. String key = (String) entry.getKey(); // 分别获得key和value
  9. String value = (String) entry.getValue();
  10. System.out.println(key + "=" + value);
  11. }// 增强for循环迭代
复制代码

:原则上map集合是无法使用增强for循环来迭代的,因为增强for循环只能针对实现了Iterable接口的集合进行迭代;Iterable是jdk5中新定义的接口,就一个方法iterator方法,只有实现了Iterable接口的类,才能保证一定有iterator方法,java有这样的限定是因为增强for循环内部还是用迭代器实现的,而实际上,我们可以通过某种方式来使用增强for循环。
  1. for(Object obj : map.entrySet()) {
  2. Map.Entry entry = (Entry) obj;  // obj 依次表示Entry
  3. System.out.println(entry.getKey() + "=" + entry.getValue());
  4. }
复制代码


5)、集合迭代注意问题:在迭代集合的过程中,不能对集合进行增删操作(会报并发访问异常);可以用迭代器的方法进行操作(子类listIterator:有增删的方法)。
6)、增强for循环注意问题:在使用增强for循环时,不能对元素进行赋值;
  1. int[] arr = {1,2,3}; for(int num : arr) {
  2. num = 0; //不能改变数组的值 }
  3. System.out.println(arr[1]); //2
复制代码
--------------------------------------------------

作者: optimisticpig    时间: 2014-3-24 16:06
  1. 增强型的for循环 优点主要体现在集合、数组遍历中,比如对 set 的遍历,一般是迭代遍历:
  2. Set<String> set = new HashSet<String>();
  3. Iterator<String> it = set.iterator();
  4. while (it.hasNext()) {
  5.       String str = it.next();
  6.       System.out.println(str);
  7. }
  8. for循环遍历:
  9. for (String str : set) {
  10.       System.out.println(str);
  11. }


  12. 优点还体现在泛型 假如 set中存放的是Object

  13. Set<Object> set = new HashSet<Object>();
  14. for循环遍历:
  15. for (Object obj: set) {
  16.       if(obj instanceof Integer){
  17.                 int aa= (Integer)obj;
  18.              }else if(obj instanceof String){
  19.                String aa = (String)obj
  20.              }
  21.               ........
  22. }
  23. 如果你用Iterator遍历,那就晕了
  24. map list 也一样

  25. 唯一的缺点就是 在遍历 集合过程中,不能对集合本身进行操作
  26.   for (String str : set) {
  27.    set.remove(str);//错误!
  28.   }
复制代码

作者: 宋超2356    时间: 2014-3-24 16:08
  1. import java.util.*;

  2. public class EFor {
  3.         public static void main(String[] args) {
  4.                 int[] arr = {1, 2, 3, 4, 5};
  5.                 for(int i : arr) {
  6.                         System.out.println(i);
  7.                 }
  8.                
  9.                 Collection c = new ArrayList();
  10.                 c.add(new String("aaa"));
  11.                 c.add(new String("bbb"));
  12.                 c.add(new String("ccc"));
  13.                 for(Object o : c) {
  14.                         System.out.println(o);
  15.                 }
  16.         }
  17. }
复制代码

一些简单的用到了增强for循环的地方,这对遍历array或者Collection很方便,但是有一些缺点。对于数组,他不能方便的访问下标值~对于容器,不如Iterator方便的删除集合中内容...
作者: 追逐    时间: 2014-3-24 16:09
optimisticpig 发表于 2014-3-24 16:06

哦哦。明白了点。谢谢
作者: 追逐    时间: 2014-3-24 16:13
菜小徐 发表于 2014-3-24 15:57
增强for循环:
foreach语句,foreach简化了迭代器。
格式:// 增强for循环括号里写两个参数,第一个是声 ...

谢谢。看了代码我明白了好多
作者: yanzhendong    时间: 2014-3-24 16:22
楼主学的好快,
作者: 刘先斌    时间: 2014-3-24 16:31
JDK1.5中增加了增强的for循环。

缺点:
  对于数组,不能方便的访问下标值;
  对于集合,与使用Interator相比,不能方便的删除集合中的内容(在内部也是调用Interator).
除了简单遍历并读取其中的内容外,不建议使用增强的for循环。

一、遍历数组

语法为:

for (Type value : array) {

    expression value;

}

//以前我们这样写:

void someFunction ()

{

    int[] array = {1,2,5,8,9};

    int total = 0;

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

    {

        total += array[i];

     }

    System.out.println(total);

}

//现在我们只需这样写(和以上写法是等价的):

void someFunction ()

{

    int[] array = {1,2,5,8,9};

    int total = 0;

    for (int n : array)

   {  

       total += n;

    }

    System.out.println(total);

}

这种写法的缺点:

显而易见,for/in(for each)循环自动控制一次遍历数组中的每一个元素,然后将它赋值给一个临时变量(如上述代码中的int n),然后在循环体中可直接对此临时变量进行操作。这种循环的缺点是:

1. 只能顺次遍历所有元素,无法实现较为复杂的循环,如在某些条件下需要后退到之前遍历过的某个元素;

2. 循环变量(i)不可见,如果想知道当前遍历到数组的第几个元素,只能这样写:

int i = 0;

for (int n : array) {

     System.out.println("This " + i + "-th element in the array is " + n);

     i++;

}

二、遍历集合

语法为:

for (Type value : Iterable) {

    expression value;

}

注意:for/in循环遍历的集合必须是实现Iterable接口的。

//以前我们这样写:

void someFunction ()

{

    List list = new ArrayList();

    list.add("Hello ");

    list.add("Java ");

    list.add("World!");

    String s = "";

    for (Iterator iter = list.iterator(); iter.hasNext();)

   {

       String temp= (String) iter.next();

       s += temp;

    }

    System.out.println(s);

}

//现在我们这样写:

void someFunction ()

{

    List list = new ArrayList();

    list.add("Hello ");

    list.add("Java ");

    list.add("World!");

    String s = "";

    for (Object o : list)

   {

       String temp = (String) o;

       s += temp;

   }

   System.out.println(s);

}

// 如果结合“泛型”,那么写法会更简单,如下:

void someFunction ()

{

    List list = new ArrayList();

    list.add("Hello ");

    list.add("Java ");

    list.add("World!");

    String s = "";

    for (String temp : list)

   {

       s += temp; //省去了对强制类型转换步骤

   }

   System.out.println(s);

}

//上述代码会被编译器转化为:

void someFunction ()

{

    List list = new ArrayList();

    list.add("Hello ");

    list.add("Java ");

    list.add("World!");

    String s = "";

    for (Iterator iter = list.iterator(); iter.hasNext(); )

   {

       String temp = iter.next();

       s += temp;

    }

    System.out.println(s);

}

这种写法的缺点:

    虽然对集合进行的for/in操作会被编译器转化为Iterator操作,但是使用for/in时,Iterator是不可见的,所以如果需要调用Iterator.remove()方法,或其他一些操作, for/in循环就有些力不从心了。 综上所述,Java 5.0中提供的增强的for循环——for/in(for each)循环能让我们的代码更加简洁,让程序员使用时更加方便,但是也有它的局限性,所以一定要根据实际需要有选择性地使用,不要盲目追求所谓的“新特性”。

作者: 追逐    时间: 2014-3-24 17:57
刘先斌 发表于 2014-3-24 16:31
JDK1.5中增加了增强的for循环。

缺点:

好的。谢谢帮忙
作者: 赵军军    时间: 2014-3-24 19:29
在J2SE5.0之前,如果你想依次读取一个数组中的内容,我想大部分人会采用以下这种方法:
        int[] arr=new int[5];
     for(int i=0;i<5;i++)
     arr=i+1;//给数组中各元素赋值
        for(int j=0;j<arr.length;j++)
     System.out.println(arr[j]);
但是在J2SE5.0之后,您完全可以采用另外一种方法,即增强的for循环(Enhanced for loop).那么上面的这个程序,我们可以用它来实现即是:
        int[] arr=new int[5];
     for(int i=0;i<5;i++)
     arr=i+1;//给数组中各元素赋值
        for(int a:arr)
     System.out.println(a);
在增强的for循环中,我们不需要去检查数组的边界,不必担心数组下标越界,这些都由增强的for循环替我们代劳了.那么增强的for循环的语法格

式是什么样子的呢?
        for(type element:array )
           {
            System.out.println(element)…}
这里有一点值得一提,就是element的类型一定要和array数组的元素的类型保持一致.我想这一点不用我太费口舌,因为在array数组中取出每一

个元素后,要存在element中,所以,两者的类型一定要保持一致喽!
如果是对象数组的话,做法也是大同小异,你只要保持element的类型和array数组中的元素类型一致辞就可以了.
作者: 追逐    时间: 2014-3-24 19:34
赵军军 发表于 2014-3-24 19:29
在J2SE5.0之前,如果你想依次读取一个数组中的内容,我想大部分人会采用以下这种方法:
        int[] arr=new ...

谢谢指点




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