08 数组

数组

一维数组

  • 为什么要有数组
    现在需要统计某公司员工的工资情况,例如计算平均工资、找到最高工资等。假设该公司有80名员工,
    用前面所学的知识,程序首先需要声明80个变量来分别记住每位员工的工资,然后在进行操作,这样做会显得很麻烦。
    为了解决这种问题,Java就提供了数组供我们使用
    结论:
    数组是存储多个变量(元素)的东西(容器)
    这多个变量的数据类型要一致
  • 数组概念
    数组是存储同一种数据类型多个元素的集合。也可以看成是一个容器。
    数组既可以存储基本数据类型,也可以存储引用数据类型(后面讲解)。
  • 数组定义格式
数据类型[] 数组名;//格式1
数据类型   数组名[];//格式2

//举例:
	int[] a; 	//定义了一个int类型的数组a; //推荐使用第一种定义方式。
	int a[];	//定义了一个int类型的a数组;
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //数组:可以理解为一个容器,可以存储多个相同数据类型的数据
        //数组:既可以存储基本类型的数据,也可也存储引用数据类型
        //数组属于引用数据类型
        //数据类型:基本数据类型4类8种和引用数据类型(类 数组 接口) 
        // new 出来的都是引用数据类型  // 每new一次都会在堆内存开辟新的空间
        //定义数组: 数据类型[] 数组名=new 数据类型[数组长度]
        //int[] arr = new int[3];     //3 代表数组长度
        //new 是为了初始化这个数组,数组只要初始化之后,才可以使用
        //所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。
        //动态初始化:由我们指定数组长度,由系统给数组元素,赋值默认值0
        int[] arr=new int[3];
        //通过索引给数组元素重新赋值
        arr[0]=10;
        arr[1]=20;
        arr[2]=30;
        //我们可以取数组中的元素
        //元素有索引,索引从0开始
        int num=arr[0];
        System.out.println(num);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
    }
}

数组的初始化(动态初始化 / 静态初始化)

——什么是数组的初始化
Java中的数组必须先初始化,然后才能使用。
所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。
——初始化的分类:
a:动态初始化: 只指定长度,由系统给出初始化值
b:静态初始化: 给出初始化值,由系统决定长度
注意事项: 这两种方式,只能使用一种,不能进行动静结合

  • 数组的初始化,动态初始化
数据类型[] 数组名 = new 数据类型[数组长度];
	//数组长度其实就是数组中元素的个数。
	//举例: int[] arr = new int[3];	定义了一个int类型的数组arr,这个数组可以存放3个int类型的值。
  • 数组的初始化,静态初始化
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,};
		//举例: int[] arr = new int[]{1,2,3};
	
数据类型[] 数组名 = {元素1,元素2,};   //简化格式
		//举例: int[] arr = {1,2,3};
  • 举例
package org.westos.demo;
import com.sun.media.sound.SoftTuning;
public class MyTest {
    public static void main(String[] args) {
        //动态初始化:由我们指定长度,由系统给出初始化值
        double[] arr = new double[5];
        System.out.println(arr[0]); //系统赋值double类型 默认值是0.0
        boolean[] booleans = new boolean[2];
        System.out.println(booleans[0]);//系统赋值boolean类型 默认值是false
        char[] chars = new char[2];
        System.out.println("bbbb"+(chars[0])+"aaaa");//系统赋值char类型 默认值是 (一个空字符)//输出bbbb aaaa
        
       //静态初始化:由我们给元素赋值,由系统计算长度
       int[] arr2=new int[]{20,10,30,40};
       arr2[0]=100;//arr2[0]原本20 重新赋值arr2[0]为100
        System.out.println(arr2[0]);//100
        //数组的静态初始化的简写方式
        int[] arr3={200,300,400};//直接大括号{}赋值
        System.out.println(arr3[0]);//200
        System.out.println(arr3);//数组的引用 //打印出来的是arr3的地址值
        
        //数组中的属性:获取动态获取数组长度的属性 length
        int len= arr3.length;  // arr3的长度: arr3.length
        System.out.println(len);
        //数组的注意事项:数组一旦定义好,长度就 不可变了
        System.out.println(arr3[5]); //这行会报错:ArrayIndexOutOfBoundsException //数组角标越界的异常 
           
        int[] arr4 = {200, 300, 400,20,2,30,92,30,20};       
        System.out.println(arr4[arr4.length-1]);  // 最后一个元素的索引=数组长度-1
    }
}

Java中的内存分配以及栈和堆的区别

在这里插入图片描述

package org.westos.demo;
import com.sun.media.sound.SoftTuning
public class MyTest {
    //局部变量:定义在 方法中  的变量或  方法声明(形参)上      的变量
    public static void main(String[] args) {// String[] args是个数组 args是方法声明(形参)上的变量 是局部变量
        int a=100;//定义在main方法中的 a 是方法中的变量  是局部变量 
    public static void test(int b){   //b是方法声明(形参)上的变量 是局部变量
        int a=1; //定义在test方法中的a是方法中的变量  是局部变量 
        b=10;
    }
}

数组的内存图解

  • 数组的内存图解1:一个数组
    定义一个数组,输出数组名称和数组中的元素值,给数组赋值,再次输出数组名称和数组中的元素值
    在这里插入图片描述
  • 数组的内存图解2:二个数组
    定义两个数组,分别输出数组名称和数组中的元素值,分别给两个数组赋值,再次输出数组名称和数组中的元素值
    在这里插入图片描述
  • 数组的内存图解3:三个引用2个数组
    定义第一个数组,定义完毕后,给数组元素赋值。赋值完毕后,再输出数组名称和元素。
    定义第二个数组,定义完毕后,给数组元素赋值。赋值完毕后,再输出数组名称和元素。
    定义第三个数组,把第一个数组的地址值赋值给它。(注意类型一致),通过第三个数组的名称去把元素重新赋值。
    最后,再次输出第一个数组数组名称和元素。
    在这里插入图片描述

数组操作的两个常见小问题越界和空指针

A:案例演示
a:ArrayIndexOutOfBoundsException:数组索引越界异常
原因:你访问了不存在的索引。
b:NullPointerException:空指针异常
原因:数组已经不在指向堆内存了。而你还用数组名去访问元素。

package org.westos.demo;
import com.sun.media.sound.SoftTuning
public class MyTest {
    public static void main(String[] args) { 
        int[] arr = new int[2];
        System.out.println(arr);
        arr=null; //人为置空
        System.out.println(arr.length);//会报错:NullPointerException  空指针异常
        //会报错  因为被人为置空后这个引用不再指向堆内存任何一个东西
    }
}

数组的操作

  • 数组的操作1遍历
    案例演示: 数组遍历:就是依次输出数组中的每一个元素。
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //遍历数组中的元素
        int[] arr = {10, 20, 30, 40, 50, 60};
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
        System.out.println("-------------------------");
        //如果是 反向遍历
        for(int i=arr.length-1;i>=0;i--){
            System.out.println(arr[i]);
        }
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //遍历 抽取成一个方法
        int[] arr={10,20,30,40,50,60};
        showArray(arr);
        int[] arr2 = {10, 20, 30, 40, 50, 60,30,60};
        showArray(arr2);
    }
    public static void showArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
  • 数组的操作2获取最值
    案例演示: 数组获取最值(获取数组中的最大值或者最小值)
//看 听懂------自己动手做出来---逻辑思维才能培养出来
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        int[] arr = {10, 20, 30, 50, 400, 60, 20};
        //定义一个参照值
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {   // 如果是求最小值 就换成 if(arr[i]<max) 就行
                max = arr[i];
            }
        }
        System.out.println("最大值" + max);
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //求最大值 抽取成一个方法
        int[] arr = {10, 20, 30, 50, 400, 60, 20};
        int max = getMax(arr);
        System.out.println("最大值" + max);
        
        int[] arr2 = {10, 20, 30, 50, 400, 60, 20, 200, 800};
        int max1 = getMax(arr2);
        System.out.println("最大值" + max1);
    }
    public static int getMax(int[] arr) {
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}
  • 数组的操作3反转
    案例演示: 数组元素反转(就是把元素对调)
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //值值交换
        int a = 10;
        int b = 20;
        // a 和b 的值交换一下 a=20 b=10;
        //方式1:采用中间变量来做 开发常用
        int t;
        t=a; //t=10
        a=b;//a=20
        b=t;//b=10
        System.out.println("a的值是" + a);
        System.out.println("b的值是" + b);
        //方式2:采用 ^ 也能换: ^ 一个数被另一数位异或两次该数不变
       /* a=a^b;
        b=a^b;//a^b^b----> b=a; //到这一步只给b重新赋值使得b的值是a 但a的值还是上一步的a^b
        a=a^b;//a^b^a--->a=b;
       */
        //方式3
        /*
        a=a+b;
        b=a-b;
        a=a-b;
        */
        //方式4
       /* a=(a+b)-(b=a);
        */
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        //把数组元素反转
        int[] arr = {10, 20, 30, 40, 50, 60}; //{60,50,40,30,20,10}
        //遍历数组:首尾元素对调 ,遍历数组的一半
        for (int i = 0; i < arr.length/2; i++) {
            int t = arr[i]; //采用中间变量t 进行值值交换
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = t;
   //例如 int t = arr[0]; arr[0] = arr[arr.length - 1]; arr[arr.length - 1 ] = t;--->10和60对调
        }
        System.out.println("----------------------");
        //再遍历下对调后的数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + ",");
        }
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        int[] arr = {10, 20, 30, 40, 50, 60, 70, 80}; //{60,50,40,30,20,10}
        for (int i = 0, j = arr.length - 1; i < j; i++, j--) {    //首尾两个元素一起换
            int t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }
}
package org.westos.demo;
public class MyTest {
    public static void main(String[] args) {
        int[] arr = {10, 20, 30, 40, 50, 60,70,80}; //{60,50,40,30,20,10}
        reverseArray(arr);
        System.out.println("----------------------");
        showArray(arr);
    }
    //反转数组元素
    private static void reverseArray(int[] arr) {
        for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
            int t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }
    //遍历数组元素
    private static void showArray(int[] arr) {

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + ",");
        }
    }
}
  • 数组的操作4查表法
    案例演示: 数组查表法(根据键盘录入索引,查找对应星期)
package org.westos.demo;
import java.util.Scanner;
public class MyTest {
    public static void main(String[] args) {
       //数组查表法(根据键盘录入索引, 查找对应星期)
       String[] arr={"星期一","星期二","星期三","星期四","星期五","星期六","星期天"};
       
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入索引 1------7");
        int index = scanner.nextInt();

       String str= getEle(index,arr);
       System.out.println(str);
    }

    private static String getEle(int index, String[] arr) {
        if(index>=0&&index<=arr.length-1){
            return arr[index];
        }
        return "错误 没有输入要求的索引";
    }
}
  • 数组的操作5基本查找
    案例演示: 数组元素查找(查找指定元素第一次在数组中出现的索引)
package org.westos.demo5;
import java.util.Scanner;
public class MyTest2 {
    public static void main(String[] args) {
        //根据元素查索引
        String[] arr = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个星期");
        String s = scanner.nextLine(); //录入字符串 用 nextLine
        
       int index= getIndex(s,arr);// 调用方法
       System.out.println("该元素的索引是"+index );
    }
    private static int getIndex(String s, String[] arr) {
        for(int i=0 ; i < arr.length ; i++){
            if(s.equals(arr[i])){  //判断字符串是否相等   用  s.equals , boolean b= s.equals("星期一");
                return i;
            }
        }
        return -1; //-1 代表没找到
    }
}

二维数组

  • 我们学校的Java基础班每个班有很多个学生,所以,可以用数组来存储,而我们又同时有很多个Java基础班。
    这个也应该用一个数组来存储。如何来表示这样的数据呢?Java就提供了二维数组供我们使用
    由此可见:其实二维数组其实就是每一个元素为一维数组的数组。
package org.westos.demo;
import com.sun.media.sound.SoftTuning;
public class ArrayDemo {
    public static void main(String[] args) {
        //一维数组:
        //二维数组:数组的元素是一个一维数组,那么这个数组叫做二维数组,数组套数组

        //定义二维数组的语法
        //动态初始化
        int[][] arr=new int[2][3]; //这个2 表示的是二维数组的长度   //这个3 表中二维数组中一维数组的长度
        //取一个二维数组中的第一个元素
        System.out.println(arr[0]); //打印出来 是二维数组中 第一个 一维数组的地址值
        System.out.println(arr[1]); //打印出来 是二维数组中 第二个 一维数组的地址值
        //取出 第一个 一维数组 中的第一个元素
        int num=arr[0][0];   //第一个 一维数组 中的第一个元素
        System.out.println(num); // 打印出来是0  是系统赋的默认值
        System.out.println(arr[0][1]);  //第一个 一维数组 中的第二个元素

        //另一个写法
       // int arr2[][] = new int[2][3];
        //还有一种写法
       // int[] arr3[] = new int[2][3];
    }
}

二维数组格式1的讲解及其内存图解

//二维数组格式1
	数据类型[][] 变量名 = new 数据类型[m][n];
	//m表示这个二维数组有多少个一维数组 必须写上
	//n表示每一个一维数组的元素个数 可选
	
//举例:
	int[][] arr = new int[3][2];
	//定义了一个二维数组arr
	//这个二维数组有3个一维数组,名称是arr[0],arr[1],arr[2]
	//每个一维数组有2个元素,可以通过arr[m][n]来获取
	//表示获取第m+1个一维数组的第n+1个元素
	
//以下格式也可以表示二维数组   //这两种格式不推荐使用
		数据类型 数组名[][] = new 数据类型[m][n];
		数据类型[] 数组名[] = new 数据类型[m][n];
  • 注意下面定义的区别
    int x,y;
    int[] x,y[];

    区别是:
    int[] x,y[];//定义了两个数组 一个是一维数组x 一个是二维数组y
    x=new int[3];
    y=new int[3][];

        // int x, y; //定义了两个int类型的变量 x,y
        // int[] x, y[]; //定义了一个一维数组x 一个二维数组y
        //   x=new int[2];
        //   y=new int[3][6];
  • 二维数组格式1的内存图解
    在这里插入图片描述1.字节码文件“MyTest.class”加载进方法区 // JVM把“main(){}”方法加载进栈内存执行,“int[][] arr”对象的引用被放在栈内存 //
    2.要new 所以在堆内存开辟空间 // 自己定义的二维数组长度为3,所以分配个3个长度的空间,其地址值是0x001,其默认值是null(因为数组是引用类型,引用类型的默认值是null) //
    3.因为这个二维数组长度为3 // 有3个一维数组 且每个一维数组有2个元素 // 所以还会初始化3个长度为2的一维数组 地址值为 0x0001 0x0002 0x0003 其默认值是0 //
    地址值 0x0001 0x0002 0x0003 会把三个null覆盖掉(二维数组里面的地址值0x0001 0x0002 0x0003通过引用指向一维数组)//
    4.初始化完成后 堆内存把二维数组的地址值0x001给向栈内存引用 // 然后栈内的0x001地址指向堆内的空间 //

二维数组格式2的讲解及其内存图解

//二维数组格式2
	数据类型[][] 变量名 = new 数据类型[m][];
		//m表示这个二维数组有多少个一维数组
		//这一次没有直接给出一维数组的元素个数,可以动态的给出。
	举例:
		int[][] arr = new int[3][];
		arr[0] = new int[2];
		arr[1] = new int[3];
		arr[2] = new int[1];
package org.westos.demo;
public class ArrayDemo {
    public static void main(String[] args) {
        //定义二维数组
        int[][] arr = new int[2][2];

        //定义两个一维数组
        int[] arrone={10,20,30};
        int[] arrrtwo={20,100,30};
        //重新给二维数组中的元素赋值
        arr[0]=arrone;
        arr[1]=arrrtwo;


        //取出100
        int i = arr[1][1];
        System.out.println(i);

        arr[1][2]=300;
        arr[1][arrrtwo.length-1]=300; //相当于 arr[1][2] = 300;
        System.out.println(arr[arr.length-1][arrrtwo.length - 1]); //打印出来300
    }
}
  • 二维数组格式2的内存图解
    在这里插入图片描述

二维数组格式3的讲解及其内存图解

//二维数组格式3
		数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…}...};
	//简化版:  //这个格式属于静态初始化:由我们指定具体的元素值,由系统给分配长度
		数据类型[][] 变量名 = {{元素…},{元素…},{元素…}};
	//举例: 
			int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
			int[][] arr = {{1,2,3},{5,6},{7}};
package org.westos.demo;
public class ArrayDemo {
    public static void main(String[] args) {
        //静态初始化
        int[][] arr=new int[][]{{10,20,30},{5,6},{6,8}};

        //简写
        int[][] arr2 = {{10, 20, 30}, {5, 6}, {6, 8}};
        System.out.println(arr[2][1]); // 8
        arr[1][0]=50;// 5改成50
    }
}

二维数组的操作

  • 二维数组练习1遍历
    案例演示
    需求:二维数组遍历
    外循环控制的是二维数组的长度,其实就是一维数组的个数。
    内循环控制的是一维数组的长度。
package org.westos.demo;
public class ArrayDemo {
    public static void main(String[] args) {
        int[][] arr = new int[][]{{10, 20, 30}, {5, 6}, {6, 8}};
      /*  System.out.println(arr[0][0]);  //一个一个遍历 太慢了
        System.out.println(arr[0][1]);
        System.out.println(arr[0][2]);
        System.out.println(arr[1][0]);
        System.out.println(arr[1][1]);
        System.out.println(arr[2][0]);
        System.out.println(arr[2][1]);*/
        //二维数组的遍历
        for (int i = 0; i < arr.length; i++) {   // arr.length为3    i < 3
            // System.out.println(arr[i]); // 打印三个一维数组的地址值
            for (int j = 0; j < arr[i].length; j++) { //arr[0].length为3;arr[1].length为2;arr[2].length为2
                System.out.println(arr[i][j]);
            }
        }
    }
}
  • 二维数组练习2求和
    案例演示
    需求:公司年销售额求和
    某公司按照季度和月份统计的数据如下:单位(万元)
    第一季度:22,66,44
    第二季度:77,33,88
    第三季度:25,45,65
    第四季度:11,66,99
package org.westos.demo;
public class ArrayDemo {
    public static void main(String[] args) {
      // int[][] arr={{22, 66, 44},{77, 33, 88},{25, 45, 65},{11, 66, 99}};  //静态初始化
        int[][] arr = new int[4][3];  //动态初始化
        
        int[] one={22, 66, 44};
        int[] two={77, 33, 88};
        int[] three={25, 45, 65};
        int[] four={11, 66, 99};

        arr[0]=one;
        arr[1]=two;
        arr[2]=three;
        arr[3]=four;

        //遍历二维数组的元素,累加求和
        int sum=0;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                sum+=arr[i][j];
            }
        }
        System.out.println("总销售额"+sum);
    }
}

案例演示
需求:打印杨辉三角形(行数可以键盘录入)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
分析:看这种图像的规律
A:任何一行的第一列和最后一列都是1
B:从第三行开始,每一个数据是它上一行的前一列和它上一行的本列之和。

步骤:
A:首先定义一个二维数组。行数如果是n,我们把列数也先定义为n。
这个n的数据来自于键盘录入。
B:给这个二维数组任何一行的第一列和最后一列赋值为1
C:按照规律给其他元素赋值
从第三行开始,每一个数据 是它 上一行的前一列 和它 上一行的本列 之和。
D:遍历这个二维数组。

package org.westos.demo;
import java.util.Scanner;
public class MyTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入行数");
        int n = scanner.nextInt();
        //构建二维数组
        int[][] arr = new int[n][n];  //  [n][n]是正方形  后续再变成三角形
        
        //1.把第一元素和最后一个元素置为1
        for (int i = 0; i < arr.length; i++) {
            arr[i][0]=1;  //第一个元素置1
            arr[i][i]=1;  //对角线元素置1
        }

        //2.算出中间元素
        //从第三行开始,从第二列开始,中间的数等于上一行的前一列和本列之和
        for (int i = 2; i < arr.length; i++) {  //从第三行开始  i = 2
            for (int j = 1; j <= i; j++) {  //从第二列开始  j = 1
                arr[i][j]=arr[i-1][j-1]+arr[i-1][j]; //前行前列 arr[i-1][j-1] ; 前行本列 arr[i-1][j]
            }
        }

        //3,打印出三角形
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j <=i; j++) {  // 打印 三角形: j <=i
                System.out.print(arr[i][j]+"\t");
            }
            System.out.println();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值