java数组

数组

一、数组概述

  1. 数组的概念:
  • 数组(array),就是多个相同类型的数据按一定顺序排列的集合,并使用一个名字命名,然后用编号区分这些数据。
  • 数组就是一个数据容器。
  1. 相关概念:
  • 数组名
  • 下标(或脚标、索引)(index)
  • 元素(element)
  • 数组的长度(length)

在这里插入图片描述

  1. 数组的特点:
  • 数组的长度一旦确定就不能修改(重要)
  • 存储的元素为相同的数据类型,可以是基本数据类型或引用数据类型
  • 有索引,创建数组时会在内存中开辟一整块连续的空间。
  • 存取元素的速度快,因为可以通过[下标],直接定位到任意一个元素。

二、数组初始化

数组使用之前需要先初始化,什么是数组初始化?就是给数组分配内存空间,并给元素赋值。

数组有两种初始化方式:

  1. 方式一:静态初始化

定义数组的同时为数组分配内存空间,并赋值。程序员只给定数组元素的初始值,不指定数组长

度,由系统决定数组的长度

格式

数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
或
数据类型[] 数组名; 
数组名 = new 数据类型[]{元素1,元素2,元素3...}; 

简化方式: 
数据类型[] 数组名 = {元素1,元素2,元素3...};//必须在一个语句中完成,不能分开两个语句写

例:

int[] arr = new int[]{1,2,3,4,5};//正确

int[] arr; 
arr = new int[]{1,2,3,4,5};//正确

int[] arr = new int[5]{1,2,3,4,5};//错误的,后面有{}指定元素列表,就不需要在 [长度]指定长度。 

//简化方式:
int[] arr = {1,2,3,4,5};//正确

int[] arr; 
arr = {1,2,3,4,5};//错误
  1. 方式二:动态初始化

程序员只给定数组的长度,后期再给给元素赋值(实际系统会先给出元素的默认值)

格式:

数据类型[] 数组名字 = new 数据类型[长度];
或
数据类型[] 数组名字;
数组名字 = new 数据类型[长度];
  • 数据类型: 指定创建的数组容器可以存储什么数据类型的数据。

  • [] : 表示数组。

  • 数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。

  • new:关键字,理解为开辟内存空间。因为数组本身是引用数据类型,所以要用new创建数组对象。

  • [长度]:数组的长度,表示数组容器中可以存储多少个元素。

    • 注意:数组有定长特性,长度一旦指定,不可更改。
    • 和水杯道理相同,买了一个2升的水杯,总容量就是2升,不能多也不能少。

例:

int[] arr = new int[5]; 

int[] arr; 
arr = new int[5];

三、数组元素的访问

  • 索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
  • 索引范围:[0, 数组的长度-1]
  • 格式:
数组名[索引]
  • 访问数组元素:
    • 数组名[索引],表示指定索引位置的元素
    • 数组名[索引]=值,表示为数组中指定索引位置的元素赋值
public static void main(String[] args) {
        //定义存储int类型数组,赋值元素1,2,3,4,5
        int[] arr = {1, 2, 3, 4, 5};
        //为0索引元素赋值为6
        arr[0] = 6;
        //获取数组0索引上的元素 
        int i = arr[0];
        System.out.println(i);//6
        //直接输出数组0索引元素
        System.out.println(arr[0]);//6
    }

四、数组的遍历

  • 数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。
  • 数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语句为: 数组名.length ,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为 数组名.length-1 。
 public static void main(String[] args) {
        int[] arr = {11, 22, 33, 44, 55};
        //打印输出数组的长度
        System.out.println("数组长度:" + arr.length);//5
        //数组遍历(正序):
        System.out.println("数组遍历:");
        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]);
        }
    }

五、数组元素的默认值

当我们使用动态初始化创建数组时:

数据类型[] 数组名字 = new 数据类型[长度];

此时只确定了数组的长度,那么数组的元素是什么值呢?

数组的元素有默认值:

在这里插入图片描述

六、 数组内存图

数组内存图分析

(1)一个数组内存图
public static void main(String[] args) {
int[] arr = new int[3]; 
System.out.println(arr);//[I@5f150435 
}

在这里插入图片描述

思考:打印arr为什么是[I@5f150435,它是数组的地址吗?

答:它不是数组的地址。

问?不是说arr中存储的是数组对象的首地址吗?

答:arr中存储的是数组的首地址,但是因为数组是引用数据类型,打印arr时,会自动调用arr数组对象的toString()方法,默认该方法实现的是对象类型名@该对象的hashCode()值的十六进制值。

问?对象的hashCode值是否就是对象内存地址?

答:不一定,因为这个和不同品牌的JVM产品的具体实现有关。例如:Oracle的OpenJDK中给出了5种实现,其中有一种是直接返回对象的内存地址,但是OpenJDK默认没有选择这种方式。

(2)两个数组内存图
public static void main(String[] args) {
	int[] arr = new int[3];
	int[] arr2 = new int[2];
	System.out.println(arr);
	System.out.println(arr2); 
}

在这里插入图片描述

(3)两个变量指向一个数组
public static void main(String[] args) {
        // 定义数组,存储3个元素
        int[] arr = new int[3];
        //数组索引进行赋值 
        arr[0] = 5;
        arr[1] = 6;
        arr[2] = 7;
        //输出3个索引上的元素值
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        //定义数组变量arr2,将arr的地址赋值给arr2
        int[] arr2 = arr;
        arr2[1] = 9;
        System.out.println(arr[1]);
    }

在这里插入图片描述

来点小练习吧!!!

/**
 用一个数组存储26个小写英文字母,并遍历显示,显示要求如:a->A
 */
public class Demo {
    public static void main(String[] args) {
        char[] chars = new char[]{'a', 'b','c','d','e', 'f','g','h','i', 'j', 'k','l','m', 'n','o','p','q', 'r','s','t','u', 'v','w','x','y','z'};
        for (int i = 0; i < chars.length; i++) {
           char s= (char) (chars[i]-32);
            System.out.println(chars[i]+"->"+s);
        }
    }
}
/**
 * 求某年某月某日是这一年的第几天
 * 闰年(1)能被 4 整除不能被 100 整除(2)能被 400 整除
 * int[] daysOfMonth = {31,28,31,30,31,30,31,31,30,31,30,31};
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println(dayOfYear(2000, 11, 13));
    }

    public static int dayOfYear(int year, int month, int days) {
        int[] daysOfMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int sum = days;
        for (int i = 0; i < month - 1; i++) {
            sum += daysOfMonth[i];
        }
        System.out.println(sum);
        if (month > 2) {
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                sum++;
            }
        }
        return sum;
    }
}
/**
 * 从1990年1月1日开始,三天打鱼两天晒网,问某年某月某日是打鱼还是晒网
 * 闰年(1)能被 4 整除不能被 100 整除(2)能被 400 整除
 * int[] daysOfMonth = {31,28,31,30,31,30,31,31,30,31,30,31};
 */
public class Demo {
    public static void main(String[] args) {
        int date = getDate(2000, 11, 22);
        if (date % 5 <=3&&date % 5>=1) {
            System.out.println("打鱼呢");
        } else {
            System.out.println("晒网呢");
        }
    }

    public static int getDate(int year, int month, int day) {
        if (year <= 1990) {
            System.out.println("要大于1990年哦");
        }
        if (month < 1 && month > 12) {
            System.out.println("月份要在1~12哦");
        }
        if (day<1 && day > 31) {
            System.out.println("日期要在1~31内哦");
        }

        int[] daysOfMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int sum = day;
        int count = 0;
        count += (year - 1 - 1990) * 365;
        for (int i = 1990; i < year - 1; i++) {
            if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
                count++;
                System.out.println(i+"是闰年哦");
            }
        }

        for (int i = 0; i < month - 1; i++) {
            sum += daysOfMonth[i];
        }
        if (month > 2) {
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                sum++;
                System.out.println(year+"是闰年哦");
            }
        }
        sum += count;
        System.out.println(sum);
        return sum;
    }
}


七、数组的基础算法

(1)统计

求数组元素的总和、均值、统计偶数个数等

思路:遍历数组,挨个的累加,判断每一个元素

 public static void main(String[] args) {
        int[] arr = {4, 5, 6, 1, 9};
        //求总和、均值
        int sum = 0;//因为0加上任何数都不影响结果
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        //均值
        double avg = (double) sum / arr.length;
        System.out.println(sum);
        System.out.println(avg);
    }
 public static void main(String[] args) {
        int[] arr = {4, 5, 6, 1, 9};
        //求总乘积
        long result = 1;
        // 因为1乘以任何数都不影响结果
        for (int i = 0; i < arr.length; i++) {
            result *= arr[i];
        }
        System.out.println(result);
        //统计偶数个数
        int even = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] % 2 == 0) {
                even++;
            }
        }
        System.out.println(even);
    }

(2)查找指定元素

查找某个指定元素在数组中的首次出现的位置(索引)

常见查找算法有顺序查找二分查找(折半查找,前提要求数组中元素是按照大小顺序排序的)

 //查找value第一次在数组中出现的index
    public static void main(String[] args) {
        int[] arr = {4, 5, 6, 1, 9};
        int value = 1;
        int index = -1;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == value) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            System.out.println(value + "不存在");
        } else {
            System.out.println(value + "的下标是" + index);
        }
    }

(3)查找最值及其位置

查找最值及其第一次出现的下标

思路:

(1)先假设第一个元素最大/最小,用变量index表示其位置,

(2)然后用index位置的元素与后面的元素一一比较

(3)用变量index时刻记录目前比对的最大/小的下标

public static void main(String[] args) {
        //求最大值及其位置
        int[] arr = {4, 5, 6, 1, 9};
        int maxIndex = 0;
        //假定索引0位置的元素最大
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > arr[maxIndex]) {
                maxIndex = i;
            }
        }
        System.out.println("最大值的下标:" + maxIndex);
        System.out.println("最大值:" + arr[maxIndex]);
    }

(4)排序之冒泡排序

Java中的经典算法之冒泡排序(Bubble Sort)

原理:比较两个相邻的元素,将值大的元素交换至右端,最大值出现在最后位置。

思路:

依次比较相邻的两个数,将小数放到前面,大数放到后面。

即第一趟,首先比较第1个和第2个元素,将小数放到前面,大数放到后面。

然后比较第2个和第3个元素,将小数放到前面,大数放到后面。

如此继续,直到比较最后两个数,将小数放到前面,大数放到后面。

重复第一趟步骤,直至全部排序完成。

 public static void main(String[] args) {
        int[] arr = {6, 3, 8, 2, 9, 1};//arr.length = 6
        
        // i=1,2,3,4,5 一共5轮
        for (int i = 1; i < arr.length; i++) {//轮数
             /*
             i=1,第1轮,j=0,1,2,3,4 arr[j]与arr[j+1]
             i=2,第2轮,j=0,1,2,3 arr[j]与arr[j+1]
             i=3,第3轮,j=0,1,2 arr[j]与arr[j+1]
             i=4,第4轮,j=0,1 arr[j]与arr[j+1] i=5,
             第5轮,j=0 arr[j]与arr[j+1]
             j=0, j<=arr.length-1-i
             */
            for (int j = 0; j <= arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    //交换位置
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        //结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

(5)数组的反转

方法有两种:

1、借助一个新数组

2、首尾对应位置交换

第一种方式:

在这里插入图片描述

public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};

        //(1)先创建一个新数组
        int[] newArr = new int[arr.length];

        //(2)复制元素
        int len = arr.length;
        for (int i = 0; i < newArr.length; i++) {
            newArr[i] = arr[len - 1 - i];
        }

        //(3)舍弃旧的,让arr指向新数组
        arr = newArr;//这里把新数组的首地址赋值给了arr 

        // (4)遍历显示
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

缺点:需要借助一个数组,浪费额外空间,原数组需要垃圾回收

第二种方式

**实现思想:**数组对称位置的元素互换
在这里插入图片描述

public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        
        //(1)计算要交换的次数: 次数 = arr.length/2 
        // (2)首尾对称位置交换 
        for (int i = 0; i < arr.length / 2; i++) {
            //循环的次数就是交换的次数 
            int temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }
       
        //(3)遍历显示
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

(6)数组的扩容

示例:当原来的数组长度不够了需要扩容,例如需要新增位置来存储10

 public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        //如果要把arr数组扩容,增加1个位置 
        // (1)先创建一个新数组,它的长度 = 旧数组的长度+1,或者也可以扩大为原来数组长度的1.5倍,2倍等 
        int[] newArr = new int[arr.length + 1];

        //(2)复制元素 
        // 注意:i<arr.length 因位arr比newArr短,避免下标越界
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        //(3)把新元素添加到newArr的最后 
        newArr[newArr.length - 1] = 10;
        //(4)如果下面继续使用arr,可以让arr指向新数组 
        arr = newArr; //(4)遍历显示
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

(1)至于新数组的长度定义多少合适,看实际情况,如果新增的元素个数确定,那么可以增加指

定长度,如果新增元素个数不确定,那么可以扩容为原来的1.5倍、2倍等

(2)数组扩容太多会造成浪费,太少会导致频繁扩容,效率低下

(6)数组元素的插入

在原数组的某个[index]插入一个元素

情形一:原数组未满

 public static void main(String[] args) {
        String[] arr = new String[5];
        arr[0] = "张三";
        arr[1] = "李四";
        arr[2] = "王五";
        /*
         * 那么目前数组的长度是5,而数组的实际元素个数是3
         * ,如果此时需要在“张三”和“李四”之间插入一个“赵 六”,
         * 即在[index=1]的位置插入“赵六”,
         * */
        //(1)移动2个元素,需要移动的起始元素下标是[1],它需要移动到[2],一共一共2个
        System.arraycopy(arr, 1, arr, 2, 2);
        //(2)插入新元素 
        arr[1] = "赵六";
        //(3)遍历显示
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

情形一:原数组已满

public static void main(String[] args) {
        String[] arr = new String[3];
        arr[0] = "张三";
        arr[1] = "李四";
        arr[2] = "王五";
        /*
         * 那么目前数组的长度是3,而数组的实际元素个数是3,
         * 如果此时需要在“张三”和“李四”之间插入一个“赵 六”,
         * 即在[index=1]的位置插入“赵六”,
         * */
        //(1)先扩容
        String[] newArr = new String[4];
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        arr = newArr;
        //(2)移动2个元素,需要移动的起始元素下标是[1],它需要移动到[2],
        // 一共一共2个
        System.arraycopy(arr, 1, arr, 2, 2);
        //(3)插入新元素 
        arr[1] = "赵六";
        //(4)遍历显示
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

(7)数组元素的删除

 public static void main(String[] args) {
        String[] arr = new String[3];
        arr[0] = "张三";
        arr[1] = "李四";
        arr[2] = "王五";
        /*
        现在需要删除“李四”,我们又不希望数组中间空着元素,该如何处理呢?
         * */
        //(1)移动元素,需要移动元素的起始下标[2],该元素需要移动到[1],一共需要移动1个元素
        System.arraycopy(arr, 2, arr, 1, 1);
        //(2)因为数组元素整体往左移动,这里本质上是复制,原来最后一个元素需要置空
        arr[2] = null;//使得垃圾回收尽快回收对应对象的内存
    }

(8)数组的二分查找

二分查找:对折对折再对折

要求:要求数组元素必须支持比较大小,并且数组中的元素已经按大小排好序

public static void main(String[] args) {
        int[] arr = {2, 5, 7, 8, 10, 15, 18, 20, 22, 25, 28};//数组是有序的
        int value = 18;
        int index = -1;
        int left = 0;
        int right = arr.length - 1;
        int mid = (left + right) / 2;
        while (left <= right) {
            //找到结束
            if (value == arr[mid]) {
                index = mid;
                break;
            }//没找到
            else if (value > arr[mid]) {//往右继续查找
                // 移动左边界,使得mid往右移动
                left = mid + 1;
            } else if (value < arr[mid]) {//往左边继续查找
                right = mid - 1;
            }
            mid = (left + right) / 2;
        }
        if (index == -1) {
            System.out.println(value + "不存在");
        } else {
            System.out.println(value + "的下标是" + index);
        }
    }

八、数组工具类

Java提供了现成的工具类,方便实现数组的相关操作。

java.util.Arrays数组工具类,提供了很多静态方法来对数组进行操作,而且如下每一个方法都有各种重载形式,以下只列出int[]类型的,其他类型的数组类推:

  • static int binarySearch(int[] a, int key) :要求数组有序,在数组中查找key是否存在,如果存在返回第一次找到的下标,不存在返回负数
  • static int[] copyOf(int[] original, int newLength) :根据original原数组复制一个长度为newLength的新数组,并返回新数组static int[] copyOfRange(int[] original, int from, int to) :复制original原数组的[from,to)构成新数组,并返回新数组
  • static boolean equals(int[] a, int[] a2) :比较两个数组的长度、元素是否完全相同
  • static void fill(int[] a, int val) :用val填充整个a数组
  • static void fill(int[] a, int fromIndex, int toIndex, int val):将a数组[fromIndex,toIndex)部分填充为val
  • static void sort(int[] a) :将a数组按照从小到大进行排序
  • static void sort(int[] a, int fromIndex, int toIndex) :将a数组的[fromIndex, toIndex)部分按照升序排列
  • static String toString(int[] a) :把a数组的元素,拼接为一个字符串,形式为:[元素1,元素2,元素3。。。]
public static void main(String[] args) {
        int[] arr = new int[5];
        // 打印数组,输出地址值 
        System.out.println(arr); // [I@2ac1fdc4 
        // 数组内容转为字符串 
        System.out.println("arr数组初始状态:" + Arrays.toString(arr));
        Arrays.fill(arr, 3);
        System.out.println("arr数组现在状态:" + Arrays.toString(arr));
        Random rand = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = rand.nextInt(100);//赋值为100以内的随机整数 
        }
        System.out.println("arr数组现在状态:" + Arrays.toString(arr));
        int[] arr2 = Arrays.copyOf(arr, 10);
        System.out.println("新数组:" + Arrays.toString(arr2));
        System.out.println("两个数组的比较结果:" + Arrays.equals(arr, arr2));
        Arrays.sort(arr);
        System.out.println("arr数组现在状态:" + Arrays.toString(arr));
    }

九、二维数组

二维数组:本质上就是元素为一维数组的一个数组。

二维数组的标记:[] []

int[][] arr; //arr是一个二维数组,可以看成元素是int[]一维数组类型的一个数组

二维数组也可以看成一个二维表,行*列组成的二维表,只不过这个二维表,每一行的列数还可能不同。但是每一个单元格中的元素的数据类型是一致的,例如:都是int,都是String等

在这里插入图片描述

二维数组的声明与初始化

//推荐 
元素的数据类型[][] 二维数组的名称;
//不推荐 
元素的数据类型 二维数组名[][];
//不推荐
元素的数据类型[] 二维数组名[];

//声明一个二维数组 
int[][] arr;

静态初始化

程序员给定元素初始值,由系统决定数组长度

//声明二维数组 
int[][] arr;
//静态初始化
arr = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
//arr = new int[3][3]{{1,2,3},{4,5,6},{7,8,9}};//错误,静态初始化,右边new 数据类型[] 中不能指定长度

//声明并同时初始化
int[][] arr = new int[][]{{1,2,3},{4,5,6},{7,8,9}}; //声明并同时初始化的简化写法
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};//声明与初始化必须在一句完成

动态初始化

程序员指定数组的长度,后期再赋值(系统会先给定元素默认初始值)

规则二维表:每一行的列数是相同的

//(1)确定行数和列数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[m][n]; 
m:表示这个二维数组有多少个一维数组。或者说一共二维表有几行 
n:表示每一个一维数组的元素有多少个。或者说每一行共有一个单元格 

//此时创建完数组,行数、列数确定,而且元素也都有默认值 
//(2)再为元素赋新值 
二维数组名[行下标][列下标] =;
public static void main(String[] args) {
        //定义一个二维数组
        int[][] arr = new int[3][2];
        //定义了一个二维数组arr 
        //这个二维数组有3个一维数组的元素
        //每一个一维数组有2个元素 
        //输出二维数组名称 
        System.out.println(arr); //地址值 [[I@175078b 

        //输出二维数组的第一个元素一维数组的名称 
        System.out.println(arr[0]); //地址值 [I@42552c 
        System.out.println(arr[1]); //地址值 [I@e5bbd6 
        System.out.println(arr[2]); //地址值 [I@8ee016 

        //输出二维数组的元素
        System.out.println(arr[0][0]); //0 
        System.out.println(arr[0][1]); //0
        //... 
    }

动态初始化(不规则二维表)

不规则二维表:每一行的列数可能不一样

//(1)先确定总行数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[总行数][]; 

//此时只是确定了总行数,每一行里面现在是null 

//(2)再确定每一行的列数,创建每一行的一维数组 
二维数组名[行下标] = new 元素的数据类型[该行的总列数]; 
//此时已经new完的行的元素就有默认值了,没有new的行还是null 

//(3)再为元素赋值 
二维数组名[行下标][列下标] =;
    public static void main(String[] args) {
        //定义数组 
        int[][] arr = new int[3][];

        System.out.println(arr); //[[I@175078b
        System.out.println(arr[1][0]);//NullPointerException 
        System.out.println(arr[0]); //null
        System.out.println(arr[1]); //null 
        System.out.println(arr[2]); //null 

        //动态的为每一个一维数组分配空间 
        arr[0] = new int[2];
        arr[1] = new int[3];
        arr[2] = new int[1];

        System.out.println(arr[0]); //[I@42552c 
        System.out.println(arr[1]); //[I@e5bbd6 
        System.out.println(arr[2]); //[I@8ee016 

        System.out.println(arr[0][0]); //0
        System.out.println(arr[0][1]); //0
        //ArrayIndexOutOfBoundsException 
        //System.out.println(arr[0][2]); //错误
        arr[1][0] = 100;
        arr[1][2] = 200;
    }

二维数组的遍历

for (int i = 0; i < 二维数组名.length; i++) {
            for (int j = 0; j < 二维数组名[i].length; j++) {
                System.out.print(二维数组名[i][j]);
            }
            System.out.println();
        }

数组操作的常见异常

1 、数组越界异常

public static void main(String[] args) {
	int[] arr = {1,2,3};
	System.out.println(arr[3]); 
}

创建数组,赋值3个元素,数组的索引就是0,1,2,没有3索引,因此我们不能访问数组中不存在的索引,程序运行后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。

在这里插入图片描述

2、 数组空指针异常

观察一下代码,运行后会出现什么结果。

public static void main(String[] args) {
	//定义数组 
	int[][] arr = new int[3][];
	System.out.println(arr[0][0]);//NullPointerException
}

因为此时数组的每一行还未分配具体存储元素的空间,此时arr[0]是null,此时访问arr[0][0]会抛出

NullPointerException 空指针异常。

在这里插入图片描述

例:输出一个如下图形,一共有 n 行,第n 行有 2n-1 个*,

完成方法 public void printStar(int n)的方法体

  	*
   ***
  *****
 *******
*********
public void printStar(int n) {
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < n - i; j++) {
			System.out.print(" ");
	}
	for (int j = 0; j < 2 * i - 1; j++) {
		System.out.print("*");
	}
		System.out.println();
	}
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值