年薪百万面试必杀题:普通for循环和增强for循环的奥秘是什么?

在开始之前,让我们高喊我们的口号:

键盘敲烂,年薪百万!

我听说关注我的人未来都会暴富哦!


目录

键盘敲烂,年薪百万!

我听说关注我的人未来都会暴富哦!

增强for

增强for遍历

格式

 细节

增强forVS普通for

区别:

 二者相互转化举例

1. 增强 for 循环 → 普通 for 循环

2. 普通 for 循环 → 增强 for 循环(可行情况)

3. 普通 for 循环 → 增强 for 循环(不可行情况)

4. 普通 for 循环 → 增强 for 循环(不可行情况)

匿名内部类

什么是匿名内部类?

匿名内部类的格式是什么?

格式更多细节有哪些?

什么时候用匿名内部类?


增强for

增强for遍历

它是jdk5以后出现的,其底层就是一个迭代器(Iterator)

所有的单列集合和数组才能用增强for进行遍历

格式

        增强for格式:
            for(数据类型 变量名: 集合/数组){

            }

        快速生成方式:
            集合的名字 + for 回车

 细节

修改增强for中的变量不会改变集合获数组中原本的数据

增强forVS普通for

区别:
特性普通 for 循环增强 for 循环
索引访问支持(可直接使用索引 i不支持(无法直接获取当前元素索引)
修改集合结构允许删除或替换元素(需谨慎处理索引)禁止删除或添加元素(会抛出 ConcurrentModificationException
遍历方式主动控制迭代过程(可跳跃、逆向遍历)被动遍历(按顺序逐个访问元素)
语法简洁度较繁琐(需定义索引变量和终止条件)简洁(无需管理索引)
适用范围适用于数组、List 等支持索引的结构适用于所有 Iterable 对象(如 ListSet、数组)
 二者相互转化举例
1. 增强 for 循环 → 普通 for 循环

场景:遍历数组并打印每个元素。

增强 for 循环

String[] names = {"Alice", "Bob", "Charlie"};
for (String name : names) {
    System.out.println(name);
}

转换为普通 for 循环

String[] names = {"Alice", "Bob", "Charlie"};
for (int i = 0; i < names.length; i++) {
    String name = names[i];
    System.out.println(name);
}
2. 普通 for 循环 → 增强 for 循环(可行情况

场景:遍历列表并计算元素总和(无需索引)。

普通 for 环

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
int sum = 0;
for (int i = 0; i < numbers.size(); i++) {
    sum += numbers.get(i);
}
System.out.println("Sum: " + sum);

转换为增强 for 循环

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
int sum = 0;
for (int num : numbers) {
    sum += num;
}
System.out.println("Sum: " + sum);
3. 普通 for 循环 → 增强 for 循环(不可行情况

场景:根据索引修改数组元素(依赖索引)。

普通 for 循环

int[] numbers = {1, 2, 3, 4};
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = numbers[i] * 2; // 依赖索引修改元素
}

无法直接转换为增强 for 循环
增强 for 循环无法获取当前元素的索引,因此无法直接修改特定位置的元素。

4. 普通 for 循环 → 增强 for 循环(不可行情况

场景:遍历过程中删除集合元素(会触发并发修改异常)。

普通 for 循环(错误示例)

List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
for (String name : names) { // 使用增强 for 循环删除元素
    if (name.startsWith("A")) {
        names.remove(name); // 抛出 ConcurrentModificationException
    }
}

 代码

 //1.创建集合并添加元素
        Collection<String> coll = new ArrayList<>();
        coll.add("zhangsan");
        coll.add("lisi");
        coll.add("wangwu");

        //2.利用增强for进行遍历
        //注意点:
        //s其实就是一个第三方变量,在循环的过程中依次表示集合中的每一个数据
        for(String s : coll){
            s = "qqq";
        }

        System.out.println(coll);//zhangsan lisi wangwu

匿名内部类

什么是匿名内部类?

隐藏了名字的类,可以写在成员位置(类的内部,方法的外部)或者局部位置(方法的内部)

匿名内部类的格式是什么?

        /*
        匿名内部类的格式:
        new 类名或者接口名(){
        重写方法;
        };
         */
        //编写匿名内部类的代码
        /*
        反编译,在out里面打开命令窗口,然后输入javap 文件名.class
        再按回车就可以看到反编译的内容。里面这里来说就表示swim是被实现的接口
        Animal是被继承的父类。
         */

格式更多细节有哪些?

别看匿名内部类简单,但是它里面包含了实现、继承、创建对象、方法重写等

一个匿名内部类其实就是一个对象(子类对象/接口的实现类对象),但是这个对象和平时看到的对象长得胖点而已。

什么时候用匿名内部类?

当方法的参数是接口或者类的时候,而且你只用使用一次实现类对象或者子类对象来传进该方法中。这个时候就不用去重新创建一个类来继承或者实现,然后在到对应类当中去new一个对象,再把这个对象传进要传的方法当中去。


 

详细解释代码:



public class
Test {
    public static void main(String[] args) {
        /*
        匿名内部类的格式:
        new 类名或者接口名(){
        重写方法;
        };
         */
        //编写匿名内部类的代码
        /*
        反编译,在out里面打开命令窗口,然后输入javap 文件名.class
        再按回车就可以看到反编译的内容。里面这里来说就表示swim是被实现的接口
        Animal是被继承的父类。
         */
        new Swim(){
            @Override
            public void swim(){
                System.out.println("重写了游泳的方法");
            }
        };
        /*
第一种实现接口的匿名内部类:
        1.一个没有名字的类:
        {
            @Override
            public void swim(){
                System.out.println("重写了游泳的方法");
            }
        }

        2.要实现游泳的接口
               Swim {
            @Override
            public void swim(){
                System.out.println("重写了游泳的方法");
            }
        }

        3.参考new 类名();要把这个没有名字的实现了游泳功能的类实例化(创建对象)
        new Swim () {
            @Override
            public void swim(){
                System.out.println("重写了游泳的方法");
            }
        };

        4.        new Swim () {
            @Override
            public void swim(){
                System.out.println("重写了游泳的方法");
            }
        }这一整个就是一个实例化的会游泳的一个对象。
         */
        /*
        第二种(继承父类的子类匿名内部类):
        1.一个没有名字的类:
        {
            @Override
            public void eat() {
                System.out.println("重写了eat方法");
            }
        };

        2.要继承父类
               Animal {
            @Override
            public void eat() {
                System.out.println("重写了eat方法");
            }
        }

        3.参考new 类名();要把这个没有名字的继承了父类的类实例化(创建对象)
        new Animal () {
            @Override
            public void eat() {
                System.out.println("重写了eat方法");
            }
        };

        4.        new Animal () {
            @Override
            public void eat() {
                System.out.println("重写了eat方法");
            }
        };这一整个就是一个继承了父类的一个对象。
         */

        new Animal(){
            @Override
            public void eat() {
                System.out.println("重写了eat方法");
            }
        };
        //在测试类中调用下面的method方法?
        //以前的方式如何调用?
        //要自己写一个子类继承Animal类
        //再创建子类的对象,传递给method方法
        Dog d = new Dog();
        method(d);
        //如果Dog 类我只要用一次,那么还需要单独定义一个类太麻烦。

        method(
                new Animal(){
                 @Override
                 public void eat(){
                     System.out.println("狗吃骨头");
                 }
                }
        );
    }
    public static void method(Animal a ){//Animal a = 子类对象 多态
        a.eat();//编译看左边,运行看右边

    }
}

正文


好啦,今天的分享就到这里,欢迎在评论区评交流,一起进步一起学习

如果你能关注我,那就是对我创作的最大鼓励啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是奋斗小杨啊

小额打赏,激励更多精彩分享!

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

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

打赏作者

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

抵扣说明:

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

余额充值