游乐游手机版
首页/AI教程/文章详情

第五天数组与面向对象基础学习笔记整理

时间:2026-05-28 16:25
数组详解:从基础到进阶的Java必备知识 数组本质上是一种容器,专门用于存储同一数据类型的多个值。你可以把它想象成一个带有编号的储物柜,每个格子存放一个数据,编号从0开始。掌握数组操作是Java编程的核心技能之一。 1 数组的定义格式与静态初始化 定义数组的语法非常简洁:数据类型[] 数组名。例如

数组详解:从基础到进阶的Java必备知识

数组本质上是一种容器,专门用于存储同一数据类型的多个值。你可以把它想象成一个带有编号的储物柜,每个格子存放一个数据,编号从0开始。掌握数组操作是Java编程的核心技能之一。

Day05-数组和面向对象基础

1. 数组的定义格式与静态初始化

定义数组的语法非常简洁:数据类型[] 数组名。例如:

int [] arr

不过,这仅仅声明了一个数组变量,并没有真正在内存中创建容器来存放数据。要让数组正式投入使用,需要对其进行初始化。

静态初始化是指在内存中为数组分配空间的同时,直接将数据放入其中。其语法格式如下:

数据类型[] 数组名 = {元素1, 元素2, 元素3...};

来看一个具体示例:

int [] arr = {11, 22, 33, 44, 55};

这样一来,数组中就包含了5个元素,依次为11、22、33、44、55。

1.1 数组遍历操作

遍历数组,简单来说就是从头到尾逐个访问数组中的每一个元素。通常使用for循环配合数组的length属性来完成:

public static void main (String [] args){
    for(int i = 0; i < arr.length; i++){
        // 这里的 arr[i] 就是当前遍历到的元素
    }
}

arr.length 表示数组的长度,因此循环从索引0一直运行到length-1,能够完整覆盖所有元素。

1.2 案例:求偶数和

来看一个实际应用:给定一个数组,需要计算其中所有偶数的总和。代码逻辑非常直观:

package com.itheima.test;

public class ArrayTest1 {
    public static void main(String[] args) {
        int[] arr1 = {-11, -22, -33, -44, -55};
        int[] arr2 = {66, 77, 88, 99, 100};
        int sum = getSum(arr2);
        System.out.println("偶数和为:" + sum);
    }

    public static int getSum(int[] arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            // arr[i] : 当前遍历到的元素
            // i : 当前的索引值
            if (arr[i] % 2 == 0) {
                sum += arr[i];
            }
        }
        return sum;
    }
}

思路非常清晰:遍历数组中的每一个元素,通过 %2==0 判断是否为偶数,如果是则累加到sum变量中。注意这里传入的是arr2数组,最终输出计算结果。

1.3 案例:求最大值

再来看一个经典问题:从一组数字中找出最大值。核心思想是“打擂算法”——先假设第一个元素是最大值,然后逐个比较,遇到更大的就更新。

package com.itheima.test;

public class ArrayTest1 {
    public static void main(String[] args) {
        int[] arr1 = {5, 44, 33, 55, 22};
        int max = getMax(arr1);
        System.out.println("最大值为:" + max);
    }

    public static int getMax(int[] arr) {
        // 1. 假设数组中的第一个元素为最大值
        int max = arr[0];
        // 2. 遍历数组,取出剩余的每一个元素进行比较
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                // 4. 如果找到更大的元素,就更新max变量的值
                max = arr[i];
            }
        }
        return max;
    }
}

注意循环从 i=1 开始,因为索引0的元素已经作为初始擂主了。

1.4 案例:数组反转操作 ***

需求:将数组 {11, 22, 33, 44, 55} 反转为 {55, 44, 33, 22, 11}。如何实现?使用双指针法向中间靠拢,依次交换头尾对应的元素。

package com.itheima.test;

public class ArrayTest1 {
    public static void main(String[] args) {
        int[] arr1 = {11, 22, 33, 44, 55};
        reverseArray(arr1);
        for (int i = 0; i < arr1.length; i++) {
            System.out.println(arr1[i]);
        }
    }

    public static void swap() {
        int[] arr = {11, 22, 33, 44, 55};
        // 第一个元素 arr[0]  最后一个元素 arr[arr.length-1]
        int temp = arr[0];
        arr[0] = arr[arr.length - 1];
        arr[arr.length - 1] = temp;
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    // 需求:对数组中的元素进行反转
    public static void reverseArray(int[] arr) {
        for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }
    }
}

核心思路:使用两个索引 start 和 end,分别从数组头部和尾部向中间移动,只要 start < end 就交换对应元素,直到两个指针相遇。这个操作非常经典,也是面试中常见的高频考点。

2. 数组的动态初始化

动态初始化指的是先创建一个指定长度的数组,但初始时不填充具体数据,后续再逐个赋值。语法格式:

int[] arr = new int[n]; // 创建一个长度为n的数组,共有n个空位

也就是说,你只需要告诉数组“我需要多少个位置”,系统会自动在内存中开辟空间,每个位置都会被赋予一个默认值(对于int类型,默认值为0)。

2.1 两种数组初始化方式的区别

  • 静态初始化:适合一开始就已经明确所有元素值的情况,由开发者自行指定数据。
  • 动态初始化:适合只知道数组长度,但具体数据后续再填充的场景,系统会赋予默认初始值。

简单记忆:明确内容用静态,只知长度用动态。

2.2 案例:评委打分

一个经典的实际场景:6位评委为选手打分(分数范围为0~100),去掉一个最高分和一个最低分,剩余4个分数求平均值即为最终得分。使用动态初始化接收分数,然后遍历找出最大值、最小值,计算总和,最后求平均。

// 由6个评委打分,分数0-100,
// 选手最终得分为:去掉一个最高分和一个最低分后,剩余4个评委打分的平均值
package com.itheima.test;

import java.util.Scanner;

public class ArrayTest3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入6个评委的分数: ");
        int[] arr = new int[6];
        for (int i = 0; i < arr.length; i++) {
            System.out.println("第" + (i + 1) + "个: ");
            arr[i] = sc.nextInt();
        }
        // 1. 找出最大值
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        // 2. 找出最小值
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        // 3. 求和
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        // 4. 计算最终得分
        double avg = (sum - max - min) / 4.0;
        System.out.println("平均值为:" + avg);
    }
}

注意:总分要先减去最高分和最低分,再除以4.0(这样才能得到小数结果)。

3. 方法参数传递

这里有一个容易踩坑的知识点:Java方法传参时,基本数据类型传递的是值的副本,而引用数据类型传递的是地址值。来看两个对比示例:

基本类型参数

// 方法参数为基本数据类型,传递的是数据值本身
public class ArgsTest1 {
    public static void main(String[] args) {
        int number = 100;
        System.out.println("调用change方法前:" + number);  // 100
        change(number);
        System.out.println("调用change方法后:" + number);   // 100
    }
    public static void change(int number) {
        number = 200;
    }
}

为什么前后两次输出都是100?因为方法接收到的是number值的副本(相当于复印件),方法内部随意修改,原始值依然保持不变。

超简记忆口诀

基本类型传参数,传递的只是一个值;方法里面随便改,外面原值不动摇。

引用类型参数(数组)

// 方法参数为引用数据类型,传递的是地址值
public class ArgsTest2 {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33, 44, 55};
        System.out.println("调用change方法之前:" + arr[0]);  // 11
        change(arr);
        System.out.println("调用change方法之后:" + arr[0]);   // 66
    } 
    public static void change(int[] arr) {
        arr[0] = 66;
    } 
}

这里传入的是数组的内存地址,方法拿着这个地址直接操作堆中的真实数据,所以修改后原数组也会随之改变。

3.1 数组常见问题

3.1.1 数组索引越界异常

当访问的索引超出了数组的有效范围(比如数组长度为3,却尝试访问arr[10]或循环时使用了 i <= length),就会抛出 ArrayIndexOutOfBoundsException。看下面这个例子:

package com.itheima.exception;

public class IndexOutOfBoundsExceptionDemo {
    /* 数组索引越界异常: IndexOutOfBoundsException 访问了数组中不存在的索引 */
    public static void main(String[] args) {
        int[] arr = {11, 22, 33};
        System.out.println(arr[10]);  // 运行时抛出异常
        for(int i = 0; i <= arr.length; i++){  // 这里i的取值范围是0,1,2,3,但最大索引只有2
            System.out.println(arr[i]);
        }
    }
}

一定要牢记:循环条件不能写成 i <= arr.length,而应该使用 i < arr.length

3.1.2 空指针异常

当将数组变量赋值为 null 时,就切断了它与堆内存中实际对象的连接,此时再访问数组元素就会引发 NullPointerException

package com.itheima.exception;

public class NullPointerExceptionDemo {
    /* 空指针异常: NullPointerException
    当引用数据类型变量被赋值为 null 之后,地址的指向被切断,
    如果还继续访问堆内存中的数据,就会引发空指针异常 */
    public static void main(String[] args) {
        int[] arr = {11, 22, 33};
        arr = null;
        System.out.println(arr[0]);  // 触发空指针异常
    }
}

记住关键点:数组变量为null时,绝对不能操作它内部的元素。

4. 二维数组

如果说一维数组是一条线,那么二维数组就像一张表格(包含行和列)。定义方式如下:

int[][] arr = new int[][] {{元素1, 元素2}, {元素1, 元素2}};
int[][] arr = {{1, 2}, {3, 4}};
public static void main(String[] args) {
    int[][] arr = {{11, 22, 33}, {44, 55, 66}};
}

外层大括号里面包含两个内层大括号,每个内层大括号代表一行数据。

4.1 二维数组遍历

遍历二维数组需要两层循环:外层循环遍历每一行(即每个一维数组),内层循环遍历该行中的每一个元素。

package com.itheima.test;

public class ArrayTest4 {
    public static void main(String[] args) {
        int[][] arr = {{11, 22, 33}, {44, 55, 66}};
        // 外层循环:遍历二维数组,取出每一个一维数组
        for (int i = 0; i < arr.length; i++) {
            // arr[i] : 当前遍历到的一维数组
            // 内层循环:继续遍历这个一维数组,取出每一个元素
            for (int j = 0; j < arr[i].length; j++) {
                System.out.println(arr[i][j]);
            }
        }
    }
}

这里 arr.length 表示二维数组的行数,arr[i].length 表示第 i 行的列数。

面向对象基础

1. 类和对象

1.1 类和对象的关系

  • 依赖关系:必须先定义类(相当于模板),然后才能根据模板创建出具体的对象(实例)。
  • 数量关系:同一个类可以new出多个不同的对象,每个对象拥有自己独立的属性值。

1.2 类的组成

一个类通常包含以下两部分:

  • 属性(成员变量):定义在方法外部,用于描述对象的状态信息。例如:
public static Student(){
    String name;
    int age;
}
  • 行为(成员方法):去掉 static 关键字的方法,用于描述对象能够执行的操作。例如:
public void study(){
    System.out.println("学习");
}

1.3 对象的创建和使用

创建对象的语法:类名 对象名 = new 类名();

Student st = new Student();

之后就可以通过 st.name 访问属性,通过 st.study() 调用方法了。

2. 对象内存图

一句话总结内存分配规则:

  1. 只有执行 new 关键字时,才会在堆内存中创建对象,分配实际存储空间。
  2. 对象名(即引用变量)存放在栈内存中,其中保存的是堆内存中的地址值。
  3. 真正存储的数据(成员变量值)位于堆内存中。
  4. 方法传递对象时,传递的是地址值,因此方法内部能够修改堆内存中的数据(前面数组的例子正是这个原理)。

3. 成员变量和局部变量的区别

对比项 成员变量 局部变量
初始化值 有默认初始化值(如int类型默认为0) 没有默认值,使用前必须显式赋值
内存位置 堆内存 栈内存
生命周期 随对象创建而存在,随对象被回收而消失 随方法调用而存在,方法执行结束即消失
作用域 在整个类的内部都有效 仅在所属的 {} 代码块内有效

理解这些区别,写代码时就能更清楚地判断变量应该定义在哪个位置。

来源:https://juejin.cn/post/7620734328046108681
上一篇AI人工智能面试教练有效提升求职面试表现 下一篇爱派Aipy一站式新一代免费开源L5级AI智能体系统
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
大班体育活动PPT制作全攻略 助力孩子成长与团队合作
AI教程 · 2026-05-30

大班体育活动PPT制作全攻略 助力孩子成长与团队合作

使用情景: 如今,大班体育活动在幼儿园和小学阶段越来越普及。家长们普遍希望孩子通过这类活动锻炼体能、结交伙伴、培养团队协作能力。因此,一份生动有趣的活动PPT成了刚需——它既能帮助教师清晰呈现活动内容,又能激发孩子的参与热情,同时吸引家长关注。 不过,要设计出既有创意又信息丰富的PPT,对于教学任务

2019年度工作总结撰写指南与详尽范文提示词
AI教程 · 2026-05-30

2019年度工作总结撰写指南与详尽范文提示词

适用需求场景: 2019年度工作总结报告 2019年即将画上句号。在这一年里,得益于公司领导的悉心指导和同事们的通力协作,各项任务均按照既定节点圆满完成,同时我也积累了丰富的实践经验与工作心得。现将全年工作进行系统梳理,主要成果与经验集中在以下几个方面:

在线AI智能制作PPT网站,一键轻松应对办公挑战
AI教程 · 2026-05-30

在线AI智能制作PPT网站,一键轻松应对办公挑战

AI制作PPT的网站推荐,轻松搞定职场演示难题 在节奏飞快的职场环境中,一份专业且精美的PPT往往是高效沟通与成功汇报的核心要素。然而,从内容构思、视觉设计到版式编排,传统的PPT制作流程极为耗时费力,常常成为职场人的痛点。是否存在一种方式,能让我们从繁琐的重复劳动中抽身,将主要精力聚焦于内容本身?

如何用AI制作幼儿园大班毕业汇报PPT范文与提示词
AI教程 · 2026-05-30

如何用AI制作幼儿园大班毕业汇报PPT范文与提示词

使用情景: 每到幼儿园大班毕业季,老师们总会迎来一个甜蜜而棘手的挑战:如何制作一份既精彩纷呈又感人至深的毕业汇报PPT?这早已不只是简单的成果展示,而是对孩子们一整年学习生活的深情回溯,更是对未来的美好期许。然而,从海量素材的筛选、版式的精心打磨,到为每个孩子撰写独一无二的成长故事,每一步都让不少教

2026年第18周Python技术周刊
AI教程 · 2026-05-30

2026年第18周Python技术周刊

本周Python生态迎来多项重要进展:多个PEP获批,涉及类型系统加固、CAPI简化与打包治理;Pip26 1新增依赖冷却机制并终止对Python3 9支持;Python打包委员会正式成立,基础架构建设稳步推进。