Java全栈(二)JavaSE:9.Java数组详解

本文详细介绍了Java中的数组概念、声明、创建、初始化、内存分析、数组操作、多维数组以及异常处理。通过实例展示了数组的普通和增强for循环遍历,以及Arrays类的常用方法如排序和转换为字符串。还探讨了冒泡排序算法,并提到了数组操作可能遇到的ArrayIndexOutOfBoundsException和NullPointerException。
摘要由CSDN通过智能技术生成

声明:本节内容为本人观看“遇见狂神说”Java教学视频后总结,仅供学习参考。

在这里插入图片描述

1.什么是Java数组

在这里插入图片描述

百度百科中对数组的定义:

所谓数组(array),就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,以便统一管理他们,然后用编号区分他们,这个名字称为数组名,编号称为下标或索引(index)。组成数组的各个变量称为数组的元素(element)。数组中元素的个数称为数组的长度(length)。
在这里插入图片描述

数组的特点:

1、数组的长度一旦确定就不能修改

2、创建数组时会在内存中开辟一整块连续的空间。

3、存取元素的速度快,因为可以通过[下标],直接定位到任意一个元素。

2.如何声明创建数组

在这里插入图片描述
在这里插入图片描述
数组的声明:

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

//不推荐
元素的数据类型  二维数组名[];
package com.oy.arrays;

public class Demo1 {
    public static void main(String[] args) {
        // 1.声明数组
        int[] num1; //方式1,推荐这种方式
        int[] num2; //c++中的语法,不推荐
        // 2.定义数组长度,会在内存中开辟对应大小的空间
        num1 = new int[10]; //设置数组长度为10,即下标为0-9
        // 3.设置数组值
        num1[0] = 0;
        num1[1] = 10;
        num1[2] = 20;
        num1[3] = 30;
        num1[4] = 40;
        num1[5] = 50;
        num1[6] = 60;
        num1[7] = 70;
        num1[8] = 80;
        num1[9] = 90;

    }
}

3.数组的三种初始方法

(1)数组初始化方式

在这里插入图片描述

4.内存分析

(1)数组内存分析

在这里插入图片描述

在这里插入图片描述

(2)两个变量指向一个数组

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]);
}

在这里插入图片描述

(3)输出数组对象及分析

package com.oy.arrays;

public class Demo8 {
    public static void main(String[] args) {
        int[] arr1 = {1,3,5,7,9};
        /*
        * 结果:[I@1b6d3586
        * 其中:`[`表示一维数组
        *      `I`表示为Int类型数组
        *      `1b6d3586`是数组对象hash值16进制体现,注意不是数组的内存地址
        * */
        System.out.println(arr1);

        String[] arr2 = {"哈哈","呵呵","嘻嘻"};
        /*
         * 结果:[Ljava.lang.String;@4554617c
         * 其中:`[`表示一维数组
         *      `L`表示为非基本类型数组
         *      `java.lang.String`表示为String类型数组
         *      `4554617c`是数组对象hash值16进制体现,注意不是数组的内存地址
         * */
        System.out.println(arr2);
    }
}

5.下标越界

在这里插入图片描述

6.数组元素的访问

  • 索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从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);
    //直接输出数组0索引元素
    System.out.println(arr[0]);
}

7.数组的使用

在这里插入图片描述

普通for循环遍历数组

package com.oy.arrays;

public class Demo2 {
    public static void main(String[] args) {
        int[] nums = {10,20,30,40,50};
        for (int i = 0; i < nums.length; i++) {
            System.out.println(nums[i]);
        }
    }
}

运行结果如下:

10
20
30
40
50

for-each循环遍历数组

package com.oy.arrays;

public class Demo2 {
    public static void main(String[] args) {
        int[] nums = {10,20,30,40,50};
        for(int num:nums){
            System.out.println(num);
        }
    }
}

运行结果如下:

10
20
30
40
50

数组作为方法的入参

package com.oy.arrays;

public class Demo3 {
    public static void main(String[] args) {
        int[] nums = {5,22,65,99,44,15};
        int max = maxArray(nums); //将数组作为参数,传入方法中
        System.out.println(max);
    }

    // 定义方法:输出int数组中的最大值
    public static int maxArray(int[] arrays){
        int max = arrays[0];
        for (int i = 1; i < arrays.length; i++) {
            if (arrays[i]>max){
                max = arrays[i];
            }
        }
        return max;
    }
}

数组作为方法的返回值

package com.oy.arrays;

public class Demo4 {
    public static void main(String[] args) {
        int[] nums = {5,22,36,88,75};
        for (int x:resArray(nums)){
            System.out.print(x+" ");
        }
    }

    //定义方法:返回反转后的数组
    public static int[] resArray(int[] array){
        int[] result = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            result[array.length-(i+1)] = array[i];
        }
        return result; //返回数组
    }
}

运行结果如下:

75 88 36 22 5

8.多维数组

在这里插入图片描述

在这里插入图片描述

package com.oy.arrays;

public class Demo5 {
    public static void main(String[] args) {
        //定义二维数组.方式一
        /**
         * 1(array[0][0]) 2(array[0][1])
         * 3(array[1][0]) 4(array[1][1])
         * 5(array[2][0]) 6(array[2][1])
         */
        int[][] nums1 = new int[3][2];
        nums1[0][0] = 1;
        nums1[0][1] = 2;
        nums1[1][0] = 3;
        nums1[1][1] = 4;
        nums1[2][0] = 5;
        nums1[2][1] = 6;

        //定义二维数组.方式二
        int[][] nums2 = {{1,2},{3,4},{5,6}};

        //获取二维数组值
        printArray(nums1[1]);

        System.out.println(nums1[2][0]);
    }



    //定义打印数组的方法
    public static void printArray(int[] array){
        for(int x:array){
            System.out.print(x + " ");
        }
        System.out.println();
    }
}

运行结果如下:

3 4 
5

(1)二维数组的声明

语法格式:

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

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

面试:

int[] x, y[];
//x是一维数组,y是二维数组

(2)二维数组的初始化

1、静态初始化
//以下格式要求声明与静态初始化必须一起完成
元素的数据类型[][] 二维数组的名称 = {
			{元素1,元素2,元素3 。。。}, 
			{第二行的值列表},
			...
			{第n行的值列表}
		};

举例:

	int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};//声明与初始化必须在一句完成
public class Array2Demo1 {
	public static void main(String[] args) {
		//定义数组
		int[][] arr = {{1,2,3},{4,5},{6}};
		
		System.out.println(arr);
		System.out.println(arr[0]);
		System.out.println(arr[1]);
		System.out.println(arr[2]);
		
		System.out.println(arr[0][0]); //1
		System.out.println(arr[1][0]); //4
		System.out.println(arr[2][0]); //6
		
		System.out.println(arr[0][1]); //2
		System.out.println(arr[1][1]); //5
		//越界
		System.out.println(arr[2][1]); //错误
	}
}
2、动态初始化(规则二维表:每一行的列数是相同的)
//(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
    
    //...
}	 
3、动态初始化(不规则:每一行的列数可能不一样)
//(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;
	}

(3) 二维数组的相关名称及其表示方式

(1)二维数组的长度/行数:

​ 二维数组名.length

(2)二维数组的某一行:

​ 二维数组名[行下标]

​ 行下标的范围:[0, 二维数组名.length-1]

(3)某一行的列数:

​ 二维数组名[行下标].length

​ 因为二维数组的每一行是一个一维数组

(4)某一个元素

​ 二维数组名[行下标][列下标]

(4) 二维数组的遍历

普通for循环

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

增强for循环

package com.oy.arrays;

public class Demo9 {
    public static void main(String[] args) {
        int[][] intArray = {{22,55},{48,76,95,32},{55}};
        for (int[] ele:intArray){
            for(int e:ele){
                System.out.print(e+"\t");
            }
            System.out.println();
        }
    }
}

9.Arrays类操作数组

在这里插入图片描述

(1)扩展:使用IDEA查看某个类下的所有方法

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

(2)Arrays类的常用方法

  • Arrays.toString(数组名):将数组变为字符串
package com.oy.arrays;

import java.util.Arrays;

public class Dem6 {
    public static void main(String[] args) {
        int[] num = {10,55,32,95,68,75,42,65,88};
        System.out.println(Arrays.toString(num));
    }
}

效果如下:

[10, 55, 32, 95, 68, 75, 42, 65, 88]
  • Arrays.sort(数组名):将数组排序,升序
package com.oy.arrays;

import java.util.Arrays;

public class Dem6 {
    public static void main(String[] args) {
        int[] num = {10,55,32,95,68,75,42,65,88};
        Arrays.sort(num); //排序,升序
        System.out.println(Arrays.toString(num));
    }
}

效果如下:

[10, 32, 42, 55, 65, 68, 75, 88, 95]

Arrays类下有许多方法,可以通过jdk文档来查看。这里不一一讲解。

10.冒泡排序

在这里插入图片描述
原理图:
https://images2018.cnblogs.com/blog/1391679/201806/1391679-20180618163321525-1936669878.gif

  • 冒泡排序就是将数组中相邻的两个元素做比较,如果大小不符合排序要求,则交换位置
  • 每一轮遍历都会产生一个最大值或最小值,且下一轮遍历就不需要比较该值。
  • 每一轮遍历都可以减少一次比较
  • 依次循环,直到结束。

代码实现:

package com.oy.arrays;

import java.util.Arrays;

public class Demo7 {
    public static void main(String[] args) {
        int[] num = {5,22,36,12,99,45,26,68,71};

        int tmp = 0;
        //第一个for循环,确定最多需要遍历的轮数(数组长度-1次)
        for (int i = 1; i < num.length; i++) {
            boolean flag = true;
            //第二个for循环,确定每一轮需要两两比较的次数。每完成一轮都会减1
            for (int j = 0; j < num.length-i; j++) {
                //如果大小不符合,则交换位置
                if (num[j]>num[j+1]){
                    tmp = num[j];
                    num[j] = num[j+1];
                    num[j+1] = tmp;
                    flag = false;
                }
            }

            //如果一轮遍历下来,都没有发生位置交换,则表示顺序已经ok。不需要继续遍历了
            if (flag){
                break;
            }
        }
        System.out.println(Arrays.toString(num));
    }
}

运行结果如下:

[5, 12, 22, 26, 36, 45, 68, 71, 99]

11.稀疏数组(扩展)

在这里插入图片描述

在这里插入图片描述

11. 数组操作的常见异常

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 空指针异常。

在这里插入图片描述

空指针异常在内存图中的表现

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值