数组的概述
数组 : 数据的组合 (一组数据) -> 容器 变量也是容器,但是变量每次只能存储一个数据;若有批量同类型的数据,可以放入到数组中进行存储; 容器类型的知识点的学习方法: 1. 如何创建容器 2. 掌握容器的增删改查四类功能 (CRUD) 3. 遍历容器 -> 遍历: 依次从容器中取出容器中的每一个元素
数组的特点
1. 数组是Java引用数据类型中的一种! 每当有数组被创建,那么一个数组类型的对象就产生了!! 2. 数组一旦被定义长度不能发生改变!如果数组的长度发生了改变,那么一定是创建新的数组! -> 弊端! //后期数组被集合取代(集合的长度是可变的),但是集合的底层其实还是数组! 3. 一个数组中的元素必须是同一数据类型; //方便管理 , 站在一个数组的角度 4. 数组中可以存储基本数据类型的元素和引用数据类型的元素; -> 好处! 数组什么都能存! //宏观角度: 整个数组概念上! 5. 数组中的每一个元素都有一个 编号 : 专业叫 索引 -> 为了方便查询元素 索引是从0开始的,一个数组中最大的索引数: 长度-1 6. 数组有维度的概念 一维: 线段 : 线段是由一个个点来组成 一维数组 : 组成一维数组的元素,可以理解成组成线段的点 二维: 面 : 面是由线段进行组成 二维数组 : 一维数组中存储一维数组 // 不用花精力研究二维数组 举例: 一维数组 : 一包烟 二维数组 : 一条烟
数组的初始化
数组的动态初始化 **数据类型[] 数组名 = new 数据类型[长度]; 格式解释: 数据类型 : 数组中元素的数据类型 [] : 一维数组 数组名 : 和变量名的作用一样,使用数组就是在使用数组的名字 -> 命名方式: 小驼峰 = : 赋值运算符 把等号右边数组本体的地址赋值给左边的数组名 new : 创建对象(数组也是对象) / 在内存中开辟空间 (有空间就会有地址值) 数据类型 : 数组中元素的数据类型 -> 要求前后的类型必须一致! 长度 : 数组中元素的个数,数组的容量! 数组的静态初始化 完整版格式 : 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3,.....}; **简化版格式 : 数据类型[] 数组名 = {元素1,元素2,元素3,.....}; 格式解释: {元素1,元素2,元素3,.....} : 静态初始化会把数组中的元素一一罗列! 动静初始化数组的区别: 动态初始化数据: 由程序员决定数组的长度/元素的个数,由计算机根据数组元素的数据类型来决定每一个元素的默认值(初始值) 整数类型(byte,short,int,long) : 0 浮点数类型(float,double) : 0.0 字符类型(char) : 空字符 -> '\u0000' 布尔类型(boolean) : false 所有的引用数据类型数组 : null 静态初始化数组: 由程序员决定每一个数组元素的具体值,由计算机自动计算数组的长度/元素的个数; 使用场景: 动态: 程序员只知道容器的长度,而不知道容器中每一个元素的具体值,选择动态 静态: 程序员明确的自动容器中每一个元素的具体值,选择静态 引用数据类型的对象和基本数据类型的变量的区别 : 输出基本数据类型变量时 : 直接看到具体的数值 输出引用数据类型对象时 : 看到的是对象在内存中的地址值
数组的增删改查四类功能
数组的增删改查四类功能 : 增 : 数组一旦被定义长度不能发生改变,没有增的功能! 删 : 数组一旦被定义长度不能发生改变,没有删的功能! 改 : 先查后改 **数组名[索引] = 要修改的值; 查 : //利用数组中元素的索引来查找元素 **数组名[索引] : 查询数组中指定索引位置上的元素值 (查: copy一份) //数组有长度属性 **数组名.length : 查询指定数组的长度/元素的个数
数组的遍历标准代码
//快捷代码: 数组名.fori 正序遍历 数组名.forr 倒序遍历 for (int i = 0; i < arr1.length; i++) { System.out.println("arr1["+i+"] = " + arr1[i]); }''''
Java内存分配
栈内存 : stack 作用1 : 给程序中方法执行提供内存空间 作用2 : 存 局部变量的 //局部 : 方法内 作用3 : 栈内存可以 表现 程序的执行流程 -> 方法进栈,方法出栈 栈内存的特点: 1. 方法的进栈出栈 : 先进后出 -> 枪的弹夹 2. 栈内存中的方法使用完毕立刻弹栈的 StackOverFLowError : 栈内存溢出错误 //只能减少方法调用的次数 堆内存 : memory -> 内存 作用1 : 存储 new 出来的东西 -> 对象的本体都在堆中 作用2 : 在JDK1.7之后常量池存储在堆内存中 堆内存的特点: 1. 只要在堆内存中开辟空间(创对象),堆内存就会给这个空间(对象)分配一个地址值 2. 堆中对象内部的数据都有 默认值 -> 数组元素的默认值: 整数类型(byte,short,int,long) : 0 浮点数类型(float,double) : 0.0 字符类型(char) : 空字符 -> '\u0000' 布尔类型(boolean) : false 所有的引用数据类型数组 : null 3. 堆内存中的对象使用完毕后,不是立即回收(死亡),而是等待 gc(垃圾回收机制) 空闲的时候回收 //能主动启动gc : System.gc() -> API OutOfMemoryError : 堆内存溢出错误 //只能减少对象的创建次数 方法区 : 存储1. 字节码对象 (先编译(字节码文件 .class文件),再运行) // 一个类文件执行后,只可能生成一个字节码对象 --> 对象类型的校验 // 字节码对象中 封装着 类的概览(目录) : 去反映一个类中有哪些成员(成员变量和成员方法) 成员 : 表示一种位置关系 -> 在类中方法外 存储2. 常量池 : 存储常量的内存容器 //常量池从JDK1.7开始 搬到了堆内存中 ---------------------------------------------------------------- 本地方法区 : 本地方法执行的区域 本地方法 : 和操作系统进行交互的方法 (本地方法在Java中会被 native 关键字修饰) 寄存器 : 和CPU的运算相关的板块
两个数组初始化的内存图
2个引用指向同一个内存地址: 任意一个引用修改内存区域,另一个引用也能看到内存数据的改变!! 操作对象的引用,本质上是操作对象在堆内存中的地址值!!
关于数组操作的2个小问题
ArrayIndexOutOfBoundsException : 数组索引超出范围异常 -> 索引越界异常 //只能是数组里出现! 产生的原因 : 访问了不存在的数组索引编号 解决办法: 1. 不访问 2. 请使用正确的索引编号 NullPointerException : 空指针异常 //只要是使用对象就可能出现此问题 产生的原因: 1. 使用了值为null的对象引用去访问了内部空间 2. 使用了值为null的对象引用去访问了对象的属性 3. 使用了值为null的对象引用去调用了对象的方法 //不要去使用值为null的对象引用!! 解决方案: 1. 不使用值为null的对象 2. 找到被使用的对象,查找这个对象什么时候被赋值为null, 修改此处代码给对象一个正确的地址值