Java循环对比:传统for循环、增强型for循环和forEach循环

1、传统for循环

传统的for循环是一种经典的循环结构,在Java中广泛使用。

以下是传统for循环的特点:

灵活控制:传统for循环使用形式为for (初始化表达式; 终止条件; 步进表达式)的语法,可以手动控制循环的索引,并根据需要执行自定义操作。

索引访问:传统for循环通过索引访问集合或数组中的元素,可以直接读取和修改元素的值。

例如:

import java.util.Arrays;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        for (int i = 0; i < numbers.size(); i++) {
            System.out.println(numbers.get(i));  // 读取元素的属性值或执行操作是允许的
            numbers.set(i, 10);  // 直接修改元素的值是允许的
        }
    }
}

底层操作:相比增强型for循环,传统for循环提供了更底层的操作,更加灵活,但也更加繁琐。

适用对象:适用于任何实现了Iterable或Iterator接口的集合类。

示例代码:

public class Demo {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        for (int i = 0; i < numbers.length; i++) {
            System.out.println(numbers[i]);
        }
    }
}

传统for循环代码结构是这样的:

for(循环变量的初始声明;循环的判定条件;改变循环变量的条件){

循环体

}

其中执行顺序是:①循环变量的初始声明(声明循环变量) ②循环的判断条件(判定是否继续执行循环,是boolean值) ③循环体(想要重复执行的代码段) ④改变循环变量的条件(用于结束循环) ⑤再回到2中判断是否跳出循环,如果判断结果是true,继续上述过程。如果判断结果是false,则跳出整个循环代码段,执行后续代码。

如测试通过遍历方式,实现为数组赋值,赋值为100,200,300,400,500

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        int[] arr = new int[5];
        int num = 100;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = num;
            num += 100;
        }
        System.out.println(Arrays.toString(arr));
    }
}

代码的输出结果是这样的:[100, 200, 300, 400, 500]

显而易见,普通for循环通过下标索引,将值赋值到了数组内部。

2、增强型for循环

增强型for循环,也称为foreach循环,是一种简化版的循环语法。它可以用于遍历数组或实现了Iterable接口的集合类。

以下是增强型for循环的特点:

语法简洁:增强型for循环使用形式为for (元素类型 元素变量 : 集合或数组)的语法,使代码更易读和编写。

只读访问:在每次迭代中,增强型for循环提供对当前元素的只读访问权限,不能直接修改元素的值。

例如:

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

public class Demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("World");
        System.out.println(list);
        for (String s : list) {
            s = "New Value";  // 尝试修改元素的值
        }
        System.out.println(list);
    }
}

 

适用对象:适用于数组或实现了Iterable接口的集合类。

示例代码:

import java.util.Arrays;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Apple", "Banana", "Orange");
        for (String fruit : list) {
            System.out.println(fruit);
        }
    }
}

 

增强型for循环代码结构是这样的:

for(接收数组元素的类型 变量名:数组){

变量名代表数组中的每一个数据

}

增强for可以遍历数组中的每一个元素,用前面的变量名来接收。我强调一下是接收,因为类型所定义的变量只是用来接收数组中各个元素,而不是将每个元素分离出来。

列如上面问题,测试通过2种遍历方式,分别实现为数组赋值,赋值为100,200,300,400,500

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        int[] arr = new int[5];
        int num = 100;
        for (int i : arr) {
            i = num;
            num += 100;
        }
        System.out.println(Arrays.toString(arr));
    }
}

代码输出结果是这样的:[0, 0, 0, 0, 0]

也就是说增强for循环根本没有将值传到数组内部。这也是普通for与增强for的区别,普通for循环可以实现为数组赋值,根据索引操作;foreach只能遍历获取,不能修改数组中的数据。

除此之外,:前面是接收数组元素的类型,这里强调的是,这里定义的类型是接受数组元素的类型,不必是数组的类型关系。

for(long|float|double|.. i:arr){
	i=num;
	num+=100;
}

其实类型没有那么严格,只要是能接收这个int型的数组arr的元素即可。当然不能接收的其他类型,比如byte,short ,char…就会报错。

 

3forEach循环

forEach是Java 8中引入的一个方法,用于遍历集合中的元素并对其执行某种操作。它可以接受一个函数作为参数,这个函数会对集合中的每个元素进行操作。这个函数可以是Lambda表达式,也可以是一个普通的函数接口。

Lambda表达式在Java 8中被引入,是一种简洁,函数式的方法来编写某些操作。Lambda表达式主要被用于创建只有一个方法的接口,这个接口可以包含一个参数列表和一个表达式或一个块语句。这种表达式或块语句就是Lambda体。

以下是Lambda表达式for循环的特点:

函数式风格:Lambda表达式for循环采用函数式编程风格,通过Lambda表达式定义循环体的操作,使代码更加简洁和易读。

自动迭代:与增强型for循环类似,Lambda表达式for循环自动迭代集合或数组中的元素,无需手动控制索引。

例如:

import java.util.Arrays;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
        // 使用Java 8的forEach和Lambda表达式
        list.forEach(fruit -> System.out.println(fruit));
    }
}

4、效率简单对比

说明:测试可能有不严谨的地方,时间,机器,执行顺序,cpu运行后效率降低也有可能,仅供参考

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

public class Demo {
    public static void main(String[] args) {
        long[] numbers = {10000L, 100000L, 1000000L, 10000000L};
        for (int j= 0; j < numbers.length; j++) {
            long times = numbers[j];
            System.out.println("操作次数:" + times);
            List<String> list = new ArrayList<>();
            List<String> list1 = new ArrayList<>();
            List<String> list2 = new ArrayList<>();
            List<String> list3 = new ArrayList<>();
            for (int i = 0; i < times; i++) {
                list.add(new String());
            }
            long startTime = System.currentTimeMillis();
            //普通for
            for (int i = 0; i < list.size(); i++) {
                list1.add(list.get(i));
            }
            long endTime = System.currentTimeMillis();
            System.out.println("普通for时间(毫秒):" + (endTime - startTime));
            //增强for
            long startTime1 = System.currentTimeMillis();
            for (String s : list) {
                list2.add(s);
            }
            long endTime1 = System.currentTimeMillis();
            System.out.println("增强for时间(毫秒):" + (endTime1 - startTime1));

            long startTime2 = System.currentTimeMillis();
            //forEach
            list.forEach(s -> list3.add(s));
            long endTime2 = System.currentTimeMillis();
            System.out.println("forEach时间(毫秒):" + (endTime2 - startTime2));
        }
    }
}

执行结果:

操作次数:10000

普通for时间(毫秒):1

增强for时间(毫秒):1

forEach时间(毫秒):59

操作次数:100000

普通for时间(毫秒):2

增强for时间(毫秒):2

forEach时间(毫秒):3

操作次数:1000000

普通for时间(毫秒):37

增强for时间(毫秒):10

forEach时间(毫秒):8

操作次数:10000000

普通for时间(毫秒):203

增强for时间(毫秒):170

forEach时间(毫秒):184

5、适用场景的选择

选择合适的循环方式取决于具体的需求和操作。以下是一些建议的使用场景:

传统for循环:适用于需要手动控制索引、执行自定义操作或修改集合或数组元素值的场景。

增强型for循环:适用于简单的遍历和只读操作,不需要修改集合或数组的元素。

Lambda表达式+forEach循环:适用于函数式编程风格,简化代码,并且无需手动控制索引的场景。

根据具体的需求,我们可以灵活选择不同的循环方式,以实现代码的简洁、可读性和性能的平衡。

猜你喜欢

转载自blog.csdn.net/xijinno1/article/details/133326054