Java入门 第六节 数组

1. 什么是数组?

  1. 在我们之前学习的过程中,数据类型分为:基本数据类型和引用数据类型,其中数组就属于引用数据类型。

  2. 在学习数组之前?我们怎么存储数据 ? 数组的出现,是为了程序设计中,处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式,这些有序排列的同类数据元素的集合称为数组。

  3. 数组定义

    • 用来存储 固定个数相同类型 的数据的容器.
    • 数组里存储的数据叫做 元素
    • 存入数组中的元素是 有顺序的。
  4. 如生活中的例子, 例如: 球类的集合-----足球,篮球,羽毛球等; 电器集合----电视机,洗衣机,电风扇等;把相同元素放在同一个容器中。

1.1 数组结构

  1. 数据结构: 数据名称,元素,下标(索引)。

    • 数组名称: 用于区分不同数组,相当于变量名称。
    • 元素: 数组中存储的 相同元素 的数据。
    • 下标(索引):数组中元数的编号,从“0”开始,访问元素通过 下标(索引) 来访问。
      数组结构
  2. 可以把数组理解为: 像一个“羊肉串” 一样将一组 相同类型 的 “变量” 穿在一起。

    • 注意, 当羊肉串的长度不能满足元素个数时,就会出现数组越界。ArrayIndexOutOfBoundsException

1.2 语法定义

  1. 根据场景不同,声明数组有两种不同的方式:

    1.静态初始化:有2种定义格式
    	数据类型[] 数组名称 = {元素0,元素1,元素2,元素3}
    	数据类型[] 数组名称= new 数据类型[]{元素0,元素1,元素2,元素3}
    2. 动态初始化:只有1种
    	数据类型[] 数据名称 = new 数据类型[元素个数];// 元数个数:length 即长度
    	数据名称[0]=元素0;
    	...
    
  2. 语法使用:

    • 静态初始化,当我们事前知道,需要存储哪些数据时候。
    public static void main(String[] args) {
            //1. 静态初始化,简化格式
            // 数据类型[] 数组名 = {元素0,元数1,元数2}
            int[] array01 = {1,2,3,4,5};
            //2. 静态初始化,完整格式
            int[] array02 =new int[]{1,2,3,4,5};
        }
    
    • 动态初始化,当我们实现不知道,需要存储哪些数据时候。
     public static void main(String[] args) {
     		//数据类型[] 数组名 = new 数据类型[length]  //length 长度 存2个元素
            String[] array = new String[2];
            // 增加数据
            array[0] = "我";
            array[1] = "是";
            array[2]="谁"; //ArrayIndexOutOfBoundsException
        }
    
  3. 错误的写法, 静态和动态不能结合写。

    String[] a =  new String[5]{1,2,3,4,5};
    
  4. 数组是引用数据类型,数组的长度用 length属性 表示,长度一旦创建是不可改变的,可以允许为0。

    • a. int[] array = new int[0];//(但是没有意义)

1.3 数组创建过程分析

  1. 首先,定义数组的时候,分为以下几个过程:

    • 数组声明:
      • int[] a; 声明一个整数类型数组; 会在 栈空间 中存放一个变量 a;相当于int[] a=null;
      • 声明数组,只是给了元素类型 和 数组名称,并不能使用数组,如果想使用就需要分配空间。
    • 分配空间:
      • a=new int[3]; 会在堆内存中开辟了3个元素的空间,堆内存中的数组地址值指向a或者是保存堆中的地址值。
      • 使用new关键字分配空间时,必须指定元素类型和 数组元素个数,即长度length。
    • 赋值:
      • a[0]=100; a[1]=30,元素是有下标的,通过下标去访问。如果不赋值整数int类型默认为 0;
  2. 声明数组和存储元素:

     public static void main(String[] args) {
            String[] str =null; //声明阶段
            str = new String[5]; // new 分配空间
            // 如果没有赋值,String[] str = new String[5];
            // str[0]值是默认为null ,则整数类型为0;
            str[0] ="h"; //跟据下标,索引赋值从0开始
            str[1] ="e";
            str[2] ="l";
            str[3] ="l";
            str[4] ="o";
            // 可以指向堆中对象
            String[] temp=null;
            temp=str;
            
        }
    
  3. 遍历数组: 即输出数组中的元素:

    	public class Demo03 {
        public static void main(String[] args) {
            int[] arr = new int[2]; //length 长度为2
    
            //添加元素
            arr[0]=10;
            arr[1]=20;
    	//TODO 如果不便了数组怎么求和?
    	// arr[0]+arr[1].... 一直加,很麻烦。
    
            //1.需要通过for循环遍历数组
            for (int i = 0; i <arr.length; i++) {
                // System.out.println(i);//输出i值:0和1
                System.out.println(arr[i]);
            }
            // 2. 错误写法  为什么?
            // for (int i = 0; i <=arr.length; i++) {}
    
    		//3.需要通过for循环遍历数组 
            for (int i = 0; i <=arr.length-1; i++) {
                // System.out.println(i);//输出i值:0和1
                System.out.println(arr[i]);
            }
    		
        }
    }
    
    
  4. 简单的理解:

    • :保存基本数据类型值变量,还有 ,类的实例对象的引用(堆中对象的引用)。
    • :动态产生的数据, 可以理解成: 关键字 new 出来的对象。
    Class oop = new Class();  oop 是类的实例 , new Class(); 是对象。
    这个oop 就是在栈中,对象在堆中,是通过实例指针操作对象,多个实例可以指向同一个对象(同上数组指向)。 基本类型的包装类是类,是存放在堆中。
    

数组创建过程

1.4 入门:数组的使用

  1. 数组的创建,存储元素,查看数组长度,遍历元素输出。
     /**
         * @author 吴琼
         * 目的: 数组的入门练习
         */
            public static void main(String[] args) {
                //  简化版 数据类型[] 数组名 = {元素0,元素1,元素2,元素3,..}
                String[] name = {"周", "杰", "伦"};
                //  完成版 数据类型[]  数组名 = new 数据类型[]{元素0,元素1,元素2,元素3,..}
                String[] name2 = new String[]{"周", "杰", "伦"};
                // 动态创建 数据类型[] 数组名 = new 数据类型[长度]; 长度 = length
                String[] name3 = new String[3]; //开辟3个空间 String 类型默认为null;
                name3[0] = "周";
                name3[1] = "杰";
                name3[2] = "伦";
    
                //查看数组长度
                System.out.println("数组的长度:" + name.length);
            /*
            name3[3] = "!"; // 超过空间就会报异常  数组角标越界
            System.out.println(name3[3]); //ArrayIndexOutOfBoundsException
            */
    
                // 输出的是地址值?为什么不同?
                System.out.println("name的地址值:" + name); // [Ljava.lang.String;@28d93b30
                System.out.println("name2的地址值:" + name2); // Ljava.lang.String;@1b6d3586
                System.out.println("name3的地址值:" + name3); // [Ljava.lang.String;@4554617c
    
                // 引用类型发生的地址值引用!
                String[] name4 = null;
                name4 = name;
                //  为什么和 name 地址值相同!
                System.out.println("name4的地址值:" + name4); //  [Ljava.lang.String;@28d93b30
    
                // 二, 单纯输出数组显示结果,不使用, 用Arrays.toString(数组名);  工具类的对象
                System.out.println("显示name数组结果:" + Arrays.toString(name));
    
    
                // 三, 遍历输出数组值 即循环输出
                for (int i = 0; i < name.length; i++) {
                    System.out.println("name数组中的值是:" + name[i]);
                }
    
                // 写法2 数组0 开始 如果i<=name2.length 数组就会越界 写成i<=name2.length-1
                for (int i = 0; i <= name2.length - 1; i++) {
                    System.out.println("name2数组的值是:" + name2[i]);
                }
            }
    
  • 输出结果:

    数组的长度:3
    name的地址值:[Ljava.lang.String;@28d93b30
    name2的地址值:[Ljava.lang.String;@1b6d3586
    name3的地址值:[Ljava.lang.String;@4554617c
    name4的地址值:[Ljava.lang.String;@28d93b30
    显示name数组结果:[,,]
    name数组中的值是:周
    name数组中的值是:杰
    name数组中的值是:伦
    name2数组的值是:周
    name2数组的值是:杰
    name2数组的值是:伦
    
  1. 简单理解 ,引用传递
    		int[] a = new int[2];
    		int[] b = {1,2,6,4,5};
    		a=b;//这条语句将导致a的引用发生变化,a也成为对b所引用的数组的引用。  
    		//结果是: [1, 2, 6, 4, 5]
    		System.out.println(Arrays.toString(a));
    
    

2. 课堂案例

2.1. 输入元素打印该元素索引

  1. 通过数组中元素,查找打印该元素的索引。
    public static void main(String[] args) {
            //1. 创建数组,添加元素
            String[] arr  = new String[3];
            arr[0]="你";
            arr[1]="是";
            arr[2]="谁";
    
            //2. 输入查找元素
            System.out.println("请输入要查找的元素: ");
            String s = new Scanner(System.in).next();
    
            //3.遍历数组, if判断
            for (int i = 0; i <=arr.length-1 ; i++) {
                if (arr[i].equals(s)){ // 为什么不使用 ==,而使用equals()?
                    System.out.println("该元素的下标为 "+i);
                }
            }
    
        }
    
  • 输出结果:

    请输入要查找的元素: 
    你
    该元素的下标为 0
    

2.2. 控制台接收,四科成绩求平均分

  1. 控制台接收输入的张三的4科成绩,并计算平均值!
    • 要求使用数组 进行存储。
/**
 * @Author wq
 *      用数组存储成绩,计算4门功课,并求平均值!
 */
public class AvgDemo {
    public static void main(String[] args) {
        double sum=0; // 3.1 求和
        // 1.定义长度为4的数组存储成绩
        double[] score = new double[4];
        // 2.遍历数组 输入成绩
        for (int i=0; i<=score.length-1;i++){
            System.out.println("请输入第"+(i+1)+"科成绩:");
            score[i]= new Scanner(System.in).nextDouble();
            // 2.1 可以做一个验证,正数就求和。
            if (score[i]>=0) {
                //3.求和
                sum += score[i];
            }else{
                System.out.println("输入有误,从新输入");
                break;
            }
        }
        // 4计算求和
        System.out.println("4门成绩的平均值是: "+sum/score.length);
        // 5.输出成绩 工具类 Arrays.toString();
        System.out.println("各科成绩:"+ Arrays.toString(score));
    }
}

2.3. 比较数组中,最大值,最小值

  1. 不知道要定义数组长度的情况下,控制台接收数组元数个数,比较元数最大值和最小值。
    • 提示:在不知道长度情况下,根据输入长度来确定数组长度。
/**
 * @Author wq
 */
public class ArrayDemo3 {
    public static void main(String[] args) {
        
        System.out.println("请输入数组比较的数量:");
        int num = new Scanner(System.in).nextInt();
        //1.在不确定存储的元素的情况下,这样节省空间
        double[] price = new double[num];
        //2.操作数组就用循环,遍历输入数组元数。
        for (int i=0;i<=price.length-1;i++){
            System.out.println("请输入第"+(i+1)+"个数:");
            // 循环输入
            price[i]= new Scanner(System.in).nextDouble();
        }
        // 输出输入商品价格
        System.out.println("输出元素: "+Arrays.toString(price));

        //3.求最大值.   ? 假设如果,比较出最小值呢?
        double max = price[0]; // 假设你的最大值是第一个(第几个都行)
        for (int i=0;i<price.length;i++){
            if (max<price[i]){
                max=price[i];
            }
        }
        System.out.println("最大值是: "+max);
    }
}
  • 输出结果:

    请输入数组比较的数量:
    4
    请输入第1个数:
    2.1
    请输入第2个数:
    36.8
    请输入第3个数:
    19.5
    请输入第4个数:
    45.9
    输出元素: [2.1, 36.8, 19.5, 45.9]
    最大值是: 45.9
    
  1. 思考 要是 求数组的最小值怎么搞?

2.4. 数组算法

2.4.1 数组后移(一)

  1. 要求:将数组中的元数整体向后移动一位。该怎么做?
    • 数组一旦定义长度,就无法改变,那怎么后移 ?
    • 提示:先搞明白一件事,从前面开始往后移动?还是从后面开始往后移动?
      在这里插入图片描述
      在这里插入图片描述
  1. 代码如下:
    /**
     *      [18,22,33,55,2,6]
     *        移动完之后!
     *          [18,18,22,33,55,2]
     */
    public class ArrayDemo4{
        public static void main(String[] args) {
            // 声明一个数组
            int[] num = new int[]{18,22,33,55,2,6};
            for (int i = num.length-1;i>0;i--){
                // 向后移动一位,从后面开始移动
                num[i] =num[i-1];  //推理图
            }
            System.out.println("数组移动之后为: "+Arrays.toString(num));
        }
    }
    
  • 输出结果:

    数组移动之后为: [18, 18, 22, 33, 55, 2]
    

2.4.2 数组任意插入(二)

  1. 2.4 数组后移(一) 案例数组后移,假设我要在任意位置插入一个元素怎么处理?

    • 一定要接着案例 2.4 数组后移(一) 接着思考。
    • 提示: 关键点,移动几次。
      在这里插入图片描述
     public static void main(String[] args) {
            int[] num = new int[]{18,22,33,55,2,6};
            System.out.println("请输入要插入的元素");
            int word = new Scanner(System.in).nextInt();
            System.out.println("请输入要插入的索引");
            //2 移动次数
            int index = new Scanner(System.in).nextInt();
            for (int i = num.length-1; i>index ; i--) {
                num[i]=num[i-1];
                System.out.println(i);
            }
            // 3 插入数组
            num[index]=word;
            System.out.println(Arrays.toString(num));
    
        }
    

3. Arrays 类中的方法

3.1 Arrays.toString(Object[] array);

  1. 返回值 String类型 ,返回数组的 字符串形式
	/**
	 * @Author wq
	 */
	public class ArraysTools {
	    public static void main(String[] args) {
	        /*Arrays.toString(Object[] array),返回String类型可以直接输出*/
	        String[] name = {"张楚岚","宝儿姐","徐三","徐四"};
	        int[]  age =new int[]{18,19,20,21};
	        
	        System.out.println(Arrays.toString(name));
	        System.out.println(Arrays.toString(age));
	    }
	}
  • 输出结果:

    [张楚岚, 宝儿姐, 徐三, 徐四]
    [18, 19, 20, 21]
    

3.2 Arrays.sort (Object[] array)

  1. void 无返回值 , 对数组按照 升序排序, 整数类型,浮点型,字符型。
	public class ArraysTools2 {
	    public static void main(String[] args) {
	        char[] chars = {'e','d','c','a'};
	        int[]  age =new int[]{18,19,20,21};
	
	        /* 升序排序,void 无法直接输出*/
	        Arrays.sort(chars);
	        Arrays.sort(age);
	
	        //排序后输出
	        System.out.println(Arrays.toString(chars));
	        System.out.println(Arrays.toString(age));
	    }
	}
  • 输出结果:

    [a, c, d, e]
    [18, 19, 20, 21]
    

3.3 Arrays.sort(Object[] array,int fromIndex ,int toIndex)

  1. 对数组元素指定范围进行排序,从formindex索引,开始 到 toindex-1 索引,范围内进行排序。
public class ArraysTools2 {
    public static void main(String[] args) {
        int[]  age =new int[]{8,7,6,5,4,3,2,1,0};

        /*相当于从6开始 到 4 结束  */
        Arrays.sort(age,2,5);  // toindex 相当于到下标为(5-1) 4 

        //排序后输出
        System.out.println(Arrays.toString(age));
    }
}
  • 输出结果:

    [8, 7, 4, 5, 6, 3, 2, 1, 0]
    

3.4 Arrays.equals(name,Object[] a,Object[] a2)

  1. 比较两个数组的内容是否相等,
public class ArraysTools3 {
    public static void main(String[] args) {
        String[] name = {"张楚岚","宝儿姐","徐三","徐四"};

        String[] name2 =new String[] {"张楚岚","宝儿姐","徐三","徐四"};

        System.out.println(Arrays.equals(name,name2));  // 主要比较的是内容是否相等
    }
}
  • 输出结果:
	true

3.5 Arrays.copyOf(Objetc[] original,newLength)

  1. 复制数组成为一个新数组,Objetc[] original原数组, newLength是要复制原数组的长度。
public class ArraysTools4 {
    public static void main(String[] args) {
        /*复制一个数组*/
        int[] num ={18,19,20,21,22};
        System.out.println(Arrays.toString(Arrays.copyOf(num,num.length)));

        String[] name = {"张楚岚","宝儿姐","徐三","徐四"};
        String[] newArrays = Arrays.copyOf(name, 3);// 有返回值 返回相应类型的数组
        System.out.println(Arrays.toString(newArrays));
    }
}

输出结果:

[张楚岚, 宝儿姐, 徐三]
[18, 19, 20, 21, 22]

4. 冒泡排序

4.1 什么是冒泡?

  1. 基本思想:是对比相邻的元数值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(相互交换连个元素的位置,从大到小,从A到Z),这样较小的元素就像气泡一样从底部上升到顶部。
    • 可以 实现升序或者降序。

排序图片

  • 图片来源于网络,如有侵权可删除。

4.2 代码实现

public class BubbleSort {
    public static void main(String[] args) {
        /*可以实现数组的升序或者降序*/
        int[] num = new int[]{89,88,87,30};

        BubbleSort.bubbleSort(num);

        System.out.println("冒泡的结果:"+Arrays.toString(num));
    }
    /**
     *
     * @param arr
     */
    public static void bubbleSort(int[] arr){
        for (int i=1;i<arr.length;i++){ // 循环比较次数为length-1次

            //比较相邻的两个元素,大的“冒泡”
            for (int j=0;j<arr.length-i;j++){  //   for (int j=0;j<arr.length-1;j++)?? 为什么-1也行!
                // core 代码 升序 比较+交换位置
                if (arr[j]>arr[j+1]){
                    // 将比较的两个值进行交换
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
            // System.out.println(Arrays.toString(arr));
        }

    }
}

输出结果:

[88, 87, 30, 89]
[87, 30, 88, 89]
[30, 87, 88, 89]
冒泡的结果:[30, 87, 88, 89]

4.3 原理分析

  • 分析图如下:
    分析图
  1. 如有有n个元素, 就循环n-1次。
  2. 外循环控制 循环比较次数,内循环控制 相邻元素比较和交换位置,如果比较不对,就不需要换。 for (int j=0;j<arr.length-i;j++) 为什么要-i 因为每次循环一次都会选出一个最大值,这样内循环不用每次都循环完,就根据 i 值变化。如上图。
  3. 每次循环的结果都会确定一个最大值。这样每次循环可以减少一次。for (int j=0;j<arr.length-1;j++); 效率低每次都循环N-1次

4.4 冒泡降序怎么实现

  1. 思考
    如果做降序排序怎么搞??
在这里插入代码片
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴琼老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值