探究for、foreach和while:循环结构的选择与优劣

       作为一个初级程序员来说,对于这三种循环并不是很了解,对于集合或者数组的一个遍历都是想起那个用哪个,并没有实际的去认识到这之间的区别,这篇博文会给大家分享一下最近在工作的遇到的这类问题,以及一些实际的应用。

一:For循环

         for循环是传统的循环结构,适用于已知循环次数或需要精确控制循环的情况。在for循环中你需要指定循环的起始条件、循环条件和循环迭代操作。for循环通常用于遍历数组,执行固定次数的操作,或者需要在每次循环中更新迭代变量的情况。

        最近在工作中遇到一个问题,就是在利用for循环遍历银行卡,并且根据条件过滤掉一些不再显示的卡,这可能导致一些意外的结果,写一些伪代码供大家参考:

public static void explainFor() {
		List<String> bankAccount = new ArrayList<String>();
		bankAccount.add("1");
		bankAccount.add("2");
		bankAccount.add("3");
		bankAccount.add("4");
		
		for (int i = 0; i < bankAccount.size(); i++) {
			String bankCard = bankAccount.get(i);
			if("1".equals(bankCard)) {
				bankAccount.remove(i);
			}
			System.out.println(bankAccount.get(i));
		}
	}
	

思考:大家可以先思考一下这种情况下的遍历会出现什么样的问题? 

细心的读者会发现,直接在for循环中删除元素会导致列表长度的改变,可能会导致遍历索引和实际元素不匹配,甚至导致一些元素被跳过或重复处理。这就出现不可逆的错误。当然这样的问题也可以设置一个临时变量只保留自己想要的值,就可以避免此类错误。

二: foreach循环 

         foreach循环用于遍历集合或数组中的元素,更加简洁方便,不需要手动管理索引或迭代变量。它适用于遍历元素数量不固定的情况,例如遍历动态长度的集合或数组。foreach循环不能对集合或数组进行修改,只能用于读取元素。

思考:foreach循环会出现上文中for循环的安全问题吗?

再回答这个问题之前,我们先去了解一下foreach循环的结构和特点:

import java.util.ArrayList;

public class ForEachExample {
    public static void main(String[] args) {
        // 遍历数组
        int[] numbers = {1, 2, 3, 4, 5};
        for (int num : numbers) {
            System.out.print(num + " ");
        }
        // 输出:1 2 3 4 5

        // 遍历List
        ArrayList<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        for (String fruit : fruits) {
            System.out.print(fruit + " ");
        }
        // 输出:Apple Banana Orange
    }
}

这是一个简单的demo,大家可以很清晰的发现,在此处的索引中并没有显示的出现类似于for循环中的下标,(展开一点原理的介绍:foreach循环底层其实是实现了Iterable接口中的iterator()方法来获取迭代器的,并且实现了接口中的hashNext()和next()方法来遍历集合中的元素的。)所以在foreach循环中是根据内容来遍历的,继而配合remove中的方法,就不会出现上述的安全问题。这也从清晰的回答了上述为什么不会出现for循环的安全问题。

对于foreach循环比起for循环也有不足的地方,如果业务的实现必须根据索引进行操作,比如特定位置元素的删除和修改,foreach循环就不是最合适的选择,这个时候就需要考虑使用传统的for循环,通过索引来访问和修改元素。

三:while循环 

        while循环是一种基本的循环结构,它根据给定的条件判断来执行循环。在while循环中,循环体会一直重复执行,直到指定的条件为false。 while循环适合处理未知循环次数的情况,因为循环次数取决于条件的满足情况 。

在分析之前大家先回想一下while循环的结构:

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

public class WhileLoopListExample {
    public static void main(String[] args) {
        // 创建一个List并添加一些元素
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        fruits.add("Grapes");
        fruits.add("Mango");

        // 使用while循环遍历List并输出元素
        System.out.println("水果列表:");
        int index = 0;
        while (index < fruits.size()) {
            String fruit = fruits.get(index);
            System.out.println(fruit);
            index++;
        }
    }
}

依据上述代码,while循环的结构还是很清晰的,先判断list中是否有值,之后再去遍历,安全性很高,对于需要先判断list集合是否为空的情况下,可以直接省去这一步骤。

虽然while循环本身不会导致特定的安全问题,但是在while循环时,需要注意以下几个方面:

  1. 死循环:如果条件判断表达式在循环体内始终为真,将会导致死循环,程序会无限循环下去,不会停止。这可能导致程序卡死,或者占用了过多的计算机资源。确保在循环条件中包含能够终止循环的条件,以避免死循环。
  2. 并发访问的问题:如果在多线程环境中使用`while`循环,需要注意并发访问的问题。如果多个线程同时对共享数据进行操作,可能导致数据不一致性或竞态条件。在这种情况下,需要考虑使用同步机制(如`synchronized`关键字)来确保线程安全。
  3. 资源泄露:在`while`循环中使用资源(如文件、网络连接等),需要确保在循环终止时正确地释放这些资源,以避免资源泄露。

总的来说,`while`循环本身没有安全问题,但使用不当可能导致程序错误、资源泄露或死循环等问题。在编写`while`循环时,要小心考虑条件、循环变量的更新,确保循环终止条件正确,并在多线程环境中考虑并发访问的问题,以保证程序的正确性和安全性。

四:总结

        在上文的描述中,三种循环各有各的特点和优势,在特定的情况下选择合适的循环方式,是一个成熟的程序员必备的能力,虽然三者得目地都是循环遍历结果,但是对于一些特殊情况就可能会导致一些安全问题的产生。因此对于三种for循环总结如下:

  1. for循环:
       - 用于已知循环次数的情况,通常用于遍历范围内的整数或按步长递增/递减的值。
       - 使用计数器或循环变量控制循环的次数。
       - 适合处理迭代次数明确的情况。
  2. while循环:
       - 用于未知循环次数的情况,循环条件在循环体内判断。
       - 循环在满足条件时重复执行。
       - 适合处理不确定循环次数的情况,条件满足时终止循环。
  3.  for-each循环:
       - 用于遍历集合或数组中的元素。
       - 简化代码,无需手动管理索引,适用于读取元素而不需要修改集合的情况。
       - 适合遍历集合的所有元素,简洁方便。

        以上就是我对三种循环的浅显理解,一篇博文的分享固然不能涵盖所有的知识,但也希望可以给一些初学者提供游戏额思路和方向,去思考这类基础的用法,从而帮助读者早日成长为可以独当一面的大神,如有疑问和思考欢迎大家评论和探讨。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香蕉炒肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值