文章目录
数组
数组概念的引入
需求
存储 两个班的学生姓名
如果采取之前的做法
String name5 = "张三";
String name6 = "李四";
String name7 = "王二麻子";
String name8 = "老约翰";
采用分组的方式 分别存放内容
String 一班 = 学生1 , 学生2, 学生3
String 二班 = 学生4 , 学生5, 学生6
概念
用于存储一组相同类型数据的数据结构
基本语法
定义数组
第一种定义方式
int i = 10;
String [] yiBan = new String[2]; // 必须设定长度
yiBan[0] = "杨雪";
yiBan[1] = "李姝辰";
第二种定义方式
String [] yiBan = {"杨雪","李姝辰"};
第三种定义方式
String [] yiBan = new String[]{"杨雪","李姝辰"};
数组和内存
在方法中定义的变量,包括基本数据类型变量和引用数据类型变量,都将在栈内存中分配空间。当超过变量的作用范围之后,这里的变量会马上回收,所占用空间将另作他用,本次课之前所讲的变量都是在栈内存分配空间的。
通过new创建的数组,还有以后要讲解的对象,将在堆内存中分配空间。
同时还可以在栈内存中定义一个引用变量,取值为分配的数组或对象空间的首地址,用来实现对数组或对象内容的访问。
当堆内存这里的内容变成垃圾后,将由垃圾回收器负责自动回收,释放所占用的内存空间。回收的时机是不确定的,并不见得马上回收,也可能程序执行完毕还没有回收,受内存剩余空间大小和垃圾回收器算法影响。
栈存变量, 堆存对象
超市收银台 比作 栈 效率要求高
超市的仓库 比作堆内存 存储空间够大
栈内存
压栈 先进后出
弹栈 后进先出
弹夹, 水桶结构
堆内存
new 关键字 , 意味着在堆内存中 开辟了一块存储空间
int [] arr = new int[3];
在栈内存保存了一个变量 arr
在堆内存开辟了一块连续的内存空间 长度为3
指向了arr 变量
垃圾回收器
程序自动运行 垃圾回收器
通过数据图的方式描述数组
细节
- 定义数组, 必须初始化(设定)长度
- 下标是从0 开始的 一个数组的长度为 n 最后一个数的下标 (n - 1)
- 通过数组[下标] 的方式 可以 获取和设置 数组的值
如何一次性的查处所有的 数组信息
获取值
sout(数组[下标])
赋值
数组[下标] = 值;
遍历
// 因为 数组是一个 包含多个数据的结构
// 需要多次 循环查询 数值内容
循环语句 , 因为数组 长度固定, 所以推荐使用for循环
String [] class1 = new String [4];
class1[0] = "杨雪";
class1[1] = "李姝辰";
class1[2] = "于志强";
class1[3] = "吴金响";
for(int i = 0 ; i < 4 ; i++){
System.out.println(class1[i]);
}
属性 length
length
数组 有一个属性 length
System.out.println(arr.length);
// 优化 遍历的方式
int [] arr = {0,1,2,3,4,5,6};
for(int i= 0 ; i< arr.length ; i++){
System.out.println(arr[i]);
}
下标越界
int [] arr = {0,1,2,3};
sout(arr[3]);
// 如果我写 arr[4] 下标越界
// ArrayIndexOutOfBoundsException
// Array Index Out Of Bounds Exception
根据数据类型不同赋予默认值
int [] arr; // 默认值 0
double [] arr ; // 0.0
String [] arr; // null (什么都没有)
案例
案例1
// 使用键盘录入 循环赋值
Scanner input = new Scanner(System.in);
int [] arr = new int[5];
for (int i = 0 ; i < arr.length ; i++){
System.out.println("请输入第"+(i+1)+"个数字");
arr[i] = input.nextInt();
}
案例2
// 使用数组计算学生们的成绩
Scanner input = new Scanner(System.in);
// 保存成绩的数组
int [] arr = new int[5];
// 计算 平均分
float countScore = 0;
float avg = 0;
// 计算最大分数 和最小分数
int max = 0;
int min = 0;
for (int i = 0 ; i < arr.length ; i++){
System.out.println("请输入第"+(i+1)+"个学生的成绩:");
arr[i] = input.nextInt();
}
// 把最大值和最小值 初始化为第一个学生的成绩
max = arr[0];
min = arr[0];
// 统计
for(int k = 0 ; k < arr.length ; k++){
// 遍历数组, 获取每一个成绩
countScore += arr[k];
// 查看
if(max < arr[k]) max = arr[k];
if(min > arr[k]) min = arr[k];
}
System.out.println("平均分是:"+(countScore/5));
System.out.println("最大值是:"+(max));
System.out.println("最小值是:"+(min));
}
案例3
/* 要求
有一个数列:8,4,2,1,23,344,12
循环输出数列的值
求数列中所有数值的和
猜数游戏
从键盘中任意输入一个数据,判断数列中是否包含此数
*/
int [] arr = {8,4,2,1,23,344,12};
// 遍历
for(int i = 0 ; i < arr.length ; i++){
System.out.println(arr[i]);
}
// 输出 所有数值的和
int sum = 0;
for(int i = 0 ; i < arr.length ; i++){
sum += arr[i];
}
System.out.println(sum);
// 从键盘录入的值
int num = 12;
// 假设 数组中没有这个数
boolean flag = false;
for(int i= 0 ; i< arr.length ; i++){
// 一旦发现有一样的数
if(num == arr[i]){
flag = true;
break;
}
}
if(flag){
System.out.println("包含此数");
}else{
System.out.println("不包含此数");
}
数组的增删改
插入(增加)
/**
* 插入操作
有一组学员的成绩{99,85,82,63, 60},将它们按降序排列。要增加一个学员的成绩,将它插入成绩序列,并保持降序
*/
public class Demo {
public static void main(String[] args) {
int [] arr = {99,85,82,63,60};
//总结 插入操作步骤
Scanner input = new Scanner(System.in);
// 1- 使用键盘录入一个整数
System.out.println("请输入一个整数!");
int num = input.nextInt();
// 2- 将数组扩容, 因为元素增加
int [] newArr = new int[arr.length + 1];
for(int i = 0 ; i < arr.length; i++){
newArr[i] = arr[i];
}
// int [] arr = {99,85,82,63,60,0};
// 3- 通过比对 把插入的数据 放到指定位置
// 循环遍历 该新数组 , 如果找到了某一个位置可以容纳 新插入的数据
//
for(int n = newArr.length - 1 ; n > 0; n--){
// 4- 排队的过程中, 一旦有人插队, 该位置的人之后的每一个人都想后移动一位
// 从后向前遍历, 如果数组中数据比num小 就向后移动
if(newArr[n-1] < num){
newArr[n] = newArr[n-1];
}else{
// 一旦不小于 使用num 替换该位置的数据
newArr[n] = num;
break;
}
}
for(int i = 0 ; i< newArr.length ; i++){
System.out.print(newArr[i] + "\t");
}
}
}
删除
/**
* 删除数组中的某个元素
* 让 之后的元素向前移动一位
*/
public class Demo1 {
public static void main(String[] args) {
int [] arr = {99,85,82,63,60};
// 删除数组中的第一个数
arr[0] = arr[1];
arr[1] = arr[2];
arr[2] = arr[3];
arr[3] = arr[4];
// 两个数组之间进行数据调换
int [] newArr = new int [arr.length-1] ;
for(int i = 0 ; i<arr.length-1; i++){
newArr[i] = arr[i];
}
// 遍历数组
for (int i= 0 ; i< newArr.length ; i++){
System.out.print(newArr[i] + "\t");
}
}
}
冒泡排序
// 任意一个数组 {5,4,6,8,3,1,9}
// 按照从小到大的顺序 排序
多个人进入一个宿舍 选宿舍老大
按照高矮个子排序, 最高的人去最后边
舞动的排序
System.out.println("排序之前="+ Arrays.toString(arr));
// i 比较的轮数
for(int i = 1; i < arr.length ; i++){
// 每一轮 比较的次数
for(int k = 0; k < arr.length - i ; k++){
if(arr[k] > arr[k+1]){
// 数据交换
int m = arr[k];
arr[k] = arr[k+1];
arr[k+1] = m;
}
}
}
选择排序
int [] arr = {4,3,2,1};
System.out.println("排序之前="+ Arrays.toString(arr));
// 选择排序 轮数
for(int i = 0 ; i < arr.length-1 ; i++){
// 每一轮比较的次数
for(int k = 1 ; k < arr.length - i ; k++){
// 固定一个位置 和他之后的每一个位置作比较
if(arr[i] > arr[i+k]){
int m = arr[i];
arr[i] = arr[i+k];
arr[i+k] = m;
}
}
}
System.out.println("排序之后="+ Arrays.toString(arr));
点名案例
/*
点名程序
1- 所有需要被点名的学生 添加到数组中
2- 使用随机数程序, 获取一个数字, 该数字对应 数组的下标
3- 为了防止重复点名,每打印一个人的名字,需要把该名字从数组中移除
*/
public class Demo2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String [] arr1 = {"杨雪","李姝辰","黄庭耀","于志强","吴金响","宋元","王悉丞"};
String [] arr = arr1;
while(true){
if(arr.length == 0 ){
System.out.println("点名完毕!!!");
break;}
// 获取随机数 0 - 1 (包含零 不包含1)
int num = (int)(Math.random()*arr.length);
System.out.println("恭喜被程序选中的==="+arr[num]);
// 删除被选择的人
for(int i = num ; i < arr.length-1 ; i++){
arr[i] = arr[i+1];
}
// 缩短数组长度
String[] newArr = new String[arr.length-1];
for(int i= 0 ; i< arr.length -1;i++){
newArr[i] = arr[i];
}
// // 使用新数组 替换旧数组
arr = newArr;
// 是否继续输入
System.out.println("是否继续 , 按0 继续");
int no = input.nextInt();
if(no != 0){break;}
}
}
}
Arrays
equals
int [] arr1 = {1,2,3,4,5};
int [] arr2 = {1,2,3,4,5};
// 数组的创建 使用 new 创建
System.out.println(arr1 == arr2); // false
boolean boo = Arrays.equals(arr1,arr2); // true
System.out.println(boo);
初次接触到 == 和 equals 的区别
== 比较的是 地址是不是同一个
equals 比较的是 内容是否一样
sort
int [] arr = {1,4,3,2,5};
System.out.println("排序前");
for(int i= 0 ; i<arr.length; i++){
System.out.print(arr[i]+"\t");
}
Arrays.sort(arr);
System.out.println("排序后");
for(int i= 0 ; i<arr.length; i++){
System.out.print(arr[i]+"\t");
}
toString
int [] arr0 = {1,4,3,2,5};
System.out.println(arr0);
// [I@1b6d3586 打印的该对象的一个地址信息
System.out.println(Arrays.toString(arr0));
fill
把数组array 中的所有元素 替换为新值
copyOf
int [] arr0 = {1,4,3,2,5};
int [] arr = Arrays.copyOf(arr0,4);
System.out.println(Arrays.toString(arr));
二维数组
定义方式
int [][] arr = new int[长度][];
arr[0][0] = 101;
int [][] arr = {{101,102,103},{201,202,203},{301,302}};
int [][] arr = new int[][]{{101,102,103},{201,202,203}}
二维数组的遍历
使用双层for循环