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


    1、传统for循环

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

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

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

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

    例如:

    1. import java.util.Arrays;
    2. import java.util.List;
    3. public class Demo {
    4. public static void main(String[] args) {
    5. List numbers = Arrays.asList(1, 2, 3, 4, 5);
    6. for (int i = 0; i < numbers.size(); i++) {
    7. System.out.println(numbers.get(i)); // 读取元素的属性值或执行操作是允许的
    8. numbers.set(i, 10); // 直接修改元素的值是允许的
    9. }
    10. }
    11. }

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

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

    示例代码:

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

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

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

    循环体

    }

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

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

    1. import java.util.Arrays;
    2. public class Demo {
    3. public static void main(String[] args) {
    4. int[] arr = new int[5];
    5. int num = 100;
    6. for (int i = 0; i < arr.length; i++) {
    7. arr[i] = num;
    8. num += 100;
    9. }
    10. System.out.println(Arrays.toString(arr));
    11. }
    12. }

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

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

    2、增强型for循环

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

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

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

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

    例如:

    1. import java.util.ArrayList;
    2. import java.util.List;
    3. public class Demo {
    4. public static void main(String[] args) {
    5. List list = new ArrayList<>();
    6. list.add("Hello");
    7. list.add("World");
    8. System.out.println(list);
    9. for (String s : list) {
    10. s = "New Value"; // 尝试修改元素的值
    11. }
    12. System.out.println(list);
    13. }
    14. }

     

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

    示例代码:

    1. import java.util.Arrays;
    2. import java.util.List;
    3. public class Demo {
    4. public static void main(String[] args) {
    5. List list = Arrays.asList("Apple", "Banana", "Orange");
    6. for (String fruit : list) {
    7. System.out.println(fruit);
    8. }
    9. }
    10. }

     

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

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

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

    }

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

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

    1. import java.util.Arrays;
    2. public class Demo {
    3. public static void main(String[] args) {
    4. int[] arr = new int[5];
    5. int num = 100;
    6. for (int i : arr) {
    7. i = num;
    8. num += 100;
    9. }
    10. System.out.println(Arrays.toString(arr));
    11. }
    12. }

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

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

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

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

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

     

    3forEach循环

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

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

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

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

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

    例如:

    1. import java.util.Arrays;
    2. import java.util.List;
    3. public class Demo {
    4. public static void main(String[] args) {
    5. List list = Arrays.asList("Apple", "Banana", "Cherry");
    6. // 使用Java 8的forEach和Lambda表达式
    7. list.forEach(fruit -> System.out.println(fruit));
    8. }
    9. }

    4、效率简单对比

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

    1. import java.util.ArrayList;
    2. import java.util.List;
    3. public class Demo {
    4. public static void main(String[] args) {
    5. long[] numbers = {10000L, 100000L, 1000000L, 10000000L};
    6. for (int j= 0; j < numbers.length; j++) {
    7. long times = numbers[j];
    8. System.out.println("操作次数:" + times);
    9. List list = new ArrayList<>();
    10. List list1 = new ArrayList<>();
    11. List list2 = new ArrayList<>();
    12. List list3 = new ArrayList<>();
    13. for (int i = 0; i < times; i++) {
    14. list.add(new String());
    15. }
    16. long startTime = System.currentTimeMillis();
    17. //普通for
    18. for (int i = 0; i < list.size(); i++) {
    19. list1.add(list.get(i));
    20. }
    21. long endTime = System.currentTimeMillis();
    22. System.out.println("普通for时间(毫秒):" + (endTime - startTime));
    23. //增强for
    24. long startTime1 = System.currentTimeMillis();
    25. for (String s : list) {
    26. list2.add(s);
    27. }
    28. long endTime1 = System.currentTimeMillis();
    29. System.out.println("增强for时间(毫秒):" + (endTime1 - startTime1));
    30. long startTime2 = System.currentTimeMillis();
    31. //forEach
    32. list.forEach(s -> list3.add(s));
    33. long endTime2 = System.currentTimeMillis();
    34. System.out.println("forEach时间(毫秒):" + (endTime2 - startTime2));
    35. }
    36. }
    37. }

    执行结果:

    操作次数: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循环:适用于函数式编程风格,简化代码,并且无需手动控制索引的场景。

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

  • 相关阅读:
    javaSE和javaEE区别
    公积金贷款额度根据什么而定
    再聊Java Stream的一些实战技能与注意点
    【代码源】每日一题 国家铁路
    ZYNQ图像处理项目——模板匹配数字识别(3)
    铁死亡化合物库
    数字图像处理——大作业 基于车道信息的违法车辆车牌识别
    如何优雅的配置 Java 微服务
    java AOP实现方式及Spring AOP总结
    品牌公关稿件怎么写?纯干货
  • 原文地址:https://blog.csdn.net/xijinno1/article/details/133326054