数组:用来存储一批同种类型的内存区域(可以理解成容器)。
数组适合做一批同种类型数据的存储。
静态初始化数组
定义数组的时候直接给数组赋值。
静态初始化数组的格式:
完整格式:数据类型【】数组名=new 数据类型【】{元素1,元素2,元素3........};
简化格式:数据类型【】数组名={元素1,元素2,元素3.............};
注意:数组变量名中存储的是数组在内存中的地址,数组是引用类型
数组的访问:数组名称【索引】
数组的长度属性:length
获取数组的长度(就是数组元素的个数):System.out.println(arr.length);
数组的最大索引:数组名.length-1//前提:元素个数大于0
数组的注意事项:
“数据类型【】数组名”也可以写成“数据类型 数组名【】”
什么类型的数组存放什么类型的数据,否则报错。
数组一旦定义出来,程序执行过程中,长度、类型就固定了。
数组的动态初始化
定义数组的时候只确定元素的类型和数组的长度,之后再存入具体数据
数组的动态初始化格式:数据类型【】数组名=new 数据类型【长度】;
当前已经知道存入的元素值,用静态初始化;
当前还不清楚要存入哪些数据,用动态初始化。
动态初始化数组的元素默认值:
数据类型 | 明细 | 默认值 |
基本类型 | byte short char int long | 0 |
float double | 0.0 | |
boolean | false | |
引用类型 | 类、接口、数组、String | null |
两种初始化的使用场景总结、注意事项说明:
动态初始化:只指定数组长度,后期赋值,适合开始知道数据的数量,但是不确定具体元素值的业务场景。
静态初始化:开始就存入元素值,适合一开始就能确定元素值的业务场景。
两种格式的写法是独立的,不可以混用。
数组遍历
遍历:就是一个一个数据的访问
搜索、数据统计等等都需要用到遍历。
for(int i=0;i<arr.length;i++)
数组元素求最大值:1.数据拿到程序中去,用数组装起来2.定义一个变量用于记录最大值,这个变量建议默认存储第一个元素值作为参照3.遍历数组的元素,如果该元素大于变量存储的元素,则替换变量存储的值为该元素。4.循环结束输出最大值。
猜数字游戏:1.动态初始化数组,存入五个随机的1-20之间的数据2.定义一个死循环,不断的猜数据,遍历数组,判断数据是否在数组中,如果在,进行对应提示并结束死循环;如果没有猜中,提示继续。
随即排名:(斗地主洗牌)1.定义一个动态初始化的数组用于录入数据2.遍历数组中的每个元素,每次随机一个索引值,让当前元素与该索引位置处的元素进行交换3.遍历输出数组中的内容即可。
数组排序:就是对数组中的元素,进行升序(由小到大)或者降序(由大到小)的操作。
数组排序的技术:
冒泡排序
每次从数组中找出最大值放在数组的后面去。
实现冒泡排序的关键步骤分析:
确定总共需要做几轮:数组的长度-1
每轮比较几次:次数规律:数组的长度-i
冒泡排序的思想:
从头开始两两比较,把较大的元素与较小的元素进行交换,每轮把当前最大的一个元素存入到数组当前的末尾。
冒泡排序的实现步骤:
1.定义一个外部循环控制总共需要冒几轮(数组的长度-1)
2.定义一个内部循环,控制每轮依次往后比较几个位置(数组长度-i)
3.如果当前位置的元素>后一个位置的元素值,两者交换
数组的内存图
JAVA内存分配、数组内存图
栈、堆、方法区、本地方法栈、寄存器
方法区:字节码文件加载时进入的内存
栈内存:方法运行时所进入的内存变量也是在这里。
堆内存:new出来的东西会在这块内存中开辟空间并产生地址
两个变量指向同一个数组:
数组使用的常见问题
1.如果访问的元素位置超过最大索引,执行时会出现(数组索引越界异常)。
2.如果数组变量中没有存储数组的地址,而是null,在访问数组信息时会出现(空指针异常)。
Debug工具的使用
自带的断点调试(排错工具),可以控制代码从断点开始一行一行的执行,然后仔细观看程序执行的情况。
工具基本使用步骤:
1.在需要控制的代码行左侧,点击一下,形成断点
2.选择使用Debug方式启动程序,启动后程序会在断点暂停
3.控制代码一行一行的往下执行。