04- 数组

本文介绍了Java中的数组概念,包括需求背景、定义方式、内存分配(栈内存和堆内存)、垃圾回收、数组操作的细节如获取和设置值、遍历、属性length等。此外,还探讨了数组的增删改操作、排序算法(冒泡排序和选择排序),以及Arrays类的相关方法(equals、sort、toString、fill、copyOf)。最后,详细讲解了二维数组的定义和遍历方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


数组

数组概念的引入

需求

存储 两个班的学生姓名

如果采取之前的做法

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循环
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值