Java基础之数组

一、数组的概述

1 数组的理解

数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理

2 数组相关的概念

  • 数组名
  • 元素
  • 角标、下标、索引
  • 数组的长度
    • 元素的个数

3 数组的特点:

1)数组是有序排列的

2)数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型

3)创建数组对象会在内存中开辟一整块连续的空间

4)数组的长度一旦确定,就不能修改

4 数组的分类:

① 按照维度:一维数组、二维数组...

② 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组

二、一维数组

1 一维数组的声明与初始化

正确方式

// 1. 一维数组的声明和初始化
int num; // 声明
num = 10; // 初始化
int id = 1001; // 声明+初始化

int[] ids;
// 1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
// 1.2 动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];

// 也是正确写法
int[] arr10 = {1,2,3}; // 类型推断,若声明和赋值不在同一行时,不可以省略new int[3]

错误方式

int[] arr1 = new int[];
int[5] arr2 = new int[];
int[] arr3 = new int[3]{1,2,3};

2 一维数组元素的引用 -- 通过索引的方式调用

// 数组的索引从0开始的,到数组的长度-1结束。
names[0] = "张三";
names[1] = "李四";
names[2] = "王五";
names[3] = "赵六";
names[4] = "靓仔";

3 数组的属性 -- length

System.out.println(names.length);
System.out.println(ids.length);

说明

  • 数组一旦初始化,其长度就是确定的。arr.length
  • 数组长度一旦确定,就不可修改

4 一维数组的遍历

for (int i = 0; i < names.length; i++) {
	System.out.println(names [i]);
}	

5 一维数组元素的默认初始化值

  • 数组元素是整形:0
  •  数组元素是浮点型:0.0
    
  •  数组元素是char型:0或'\u0000'(非'0')
    
  •  数组元素是boolean型:false
    
  •  数组元素是引用数据类型:null
    

6 一维数组的内存解析

三、二维数组

1 如何理解二维数组

数组属于引用数组类型

数组的元素也可以是引用数据类型

一个一维数组A的元素如果还是一个一维数组类型的,则次数组A称为二维数组

2 二维数组的声明与初始化

正确方式

int[] arr = new int[] { 1, 2, 3 };// 一维数组
// 静态初始化
int[][] arr1 = new int[][] { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8 } };
// 动态初始化1
String[][] arr2 = new String[3][2];
// 动态初始化2
String[][] arr3 = new String[3][];

int[] arr4[] = new int[][] { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8 } };
int arr5[][] =  { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8 } };

错误方式

int[][] arr4 = new int[][2];
int[][] arr5 = new int[][];
int[][] arr6 = new int[3][2] { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8 } };

2 二维数组元素的引用 -- 通过索引的方式调用

System.out.println(arr1[0][1]); // 2
System.out.println(arr2[1][1]); // null

arr3[1] = new String[4];
System.out.println(arr3[1][0]); // 若在声明时未指明第二行的元素,会报错

3 数组的属性 -- length

System.out.println(arr1.length);
System.out.println(arr1[0].length);

4 二维数组的遍历

for (int i = 0; i < arr4.length; i++) {
		for (int j = 0; j < arr4[i].length; j++) {
			System.out.print(arr4[i][j] + "\t");
		}
		System.out.println();
	}

5 二维数组元素的默认初始化值

  • 规定:二维数组分为外层数组的元素,内层数组的元素

    • int[][] arr = new int[3][4];
    • 外层元素:arr[0],arr[1]等
    • 内层元素:arr[0][0],arr[1][2]等
  • 针对于初始化方式一:int[][] arr7 = new int[3][2];

    • 外层元素的初始化值为:地址值
    • 内层元素的初始化值为:与一维数组初始化情况相同
  • 针对于初始化方式二:String[][] arr9 = new String[3][2];

    •    外层元素的初始化值为:null
      
    •    内层元素的初始化值为:不能调用,会报错
      

6 二维数组的内存解析

四、数组的常见算法

1.数组的创建于元素赋值

杨辉三角(二维数组)、回形数(二维数组)、6个数,1-30之间随机生成且不重复

/*
 * 杨辉三角练习题
 * 	使用二维数组打印一个10行的杨辉三角
 */

public static void main(String[] args) {
    // 1.声明并初始化二维数组
    int[][] yangHui = new int[10][];

    // 2.给数组的元素赋值
    for (int i = 0; i < yangHui.length; i++) {
        yangHui[i] = new int[i + 1];

        //			2.1 给首末元素赋值
        yangHui[i][0] = yangHui[i][i] = 1;
        //			2.2 给每行的非首末元素赋值
        //			if (i > 1) {
        for (int j = 1; j < yangHui[i].length - 1; j++) {
            yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
            //				}
        }
    }

    // 3.遍历二维数组
    for (int i = 0; i < yangHui.length; i++) {
        for (int j = 0; j < yangHui[i].length; j++) {
            System.out.print(yangHui[i][j] + " ");
        }
        System.out.println();
    }
}

2.针对于数值型的数组

最大值、最小值、总和、平均数等

/*
 * 算法的考查:求数值型数组中元素的最大值、最小值、平均数、总和等
 * 
 * 定义一个int型的一维数组,包含10个元素,分别赋值一些随机整数,然后求出所有元素的最大值,最小值,和值,
 * 	平均值,并输出。
 * 要求:所有随机数都是两位数
 * 
 * 提示:
 * 	[0,1)*90->[0,90)+10->[10,100)->[10,99]
 * 	(int)(Math.random()*90+10)
 */

public static void main(String[] args) {
    int[]  arr = new int[10];

    for (int i = 0; i < arr.length; i++) {
        arr[i] = (int)(Math.random() * 90 + 10);

    }

    // 最大值
    int max = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i];
        }
    }
    System.out.println("最大值:" + max);

    // 最小值
    int min = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (min > arr[i]) {
            min = arr[i];
        }
    }
    System.out.println("最小值:" + min);

    // 总和
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    System.out.println("总和:" + sum);

    // 平均值
    int avgVaule = sum / arr.length;
    System.out.println("平均值:" + avgVaule);
}

3.数组的赋值与复制

int[] array1, array2;
array1 = new int[] {2,3,5,7,11,13,17,19};

3.1 赋值

	public static void main(String[] args) {
		int[] array1, array2;
		
		array1 = new int[] {2,3,5,7,11,13,17,19};
		
		for (int i = 0; i < array1.length; i++) {
			System.out.print(array1[i] + "\t");
		}
		
		array2 = array1;
		System.out.println();
		
		for (int i = 0; i < array2.length; i++) {
			if (i % 2 == 0) {
				array2[i] = i;
			}
			System.out.print(array1[i] + "\t");
		}
	}

如何理解

将array1保存的数组的地址值赋给了array2,使得array1和array2共同执行堆空间中的同一个数组实体

3.2 复制

/*
  * 拓展:修改题目,实现array2对array1数组的复制
 * 
 */

public static void main(String[] args) {
    int[] array1, array2;

    array1 = new int[] {2,3,5,7,11,13,17,19};

    for (int i = 0; i < array1.length; i++) {
        System.out.print(array1[i] + "\t");
    }

    array2 = new int[array1.length];
    System.out.println();

    for (int i = 0; i < array2.length; i++) {
        array2[i] = array1[i];
        System.out.print(array2[i] + "\t");
    }	
}

如何理解

通过new的方式,给array2在堆空间中新开辟了数组的空间,将array1数组中的元素值一个一个的赋值给array2

4.数组的反转

public static void main(String[] args) {
    String[] arr = new String[] {"jj","dd","mm","bb","gg","aa"};

    String[] arr1 = new String[arr.length];
    
    // 数组的反转
    for (int i = 0; i < arr.length / 2; i++) {
    	String temp = arr[i];
    	arr[i] = arr[arr.length - i - 1];
    	arr[arr.length - i - 1] = temp;
    }
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i] + "\t");
    }
}

5.数组中指定元素的查找:搜索、检索

5.1 线性查找

实现思路:通过遍历的方式,一个一个的数据进行比较、查找。

适应性:具有普遍适用性

public static void main(String[] args) {
    String[] arr = new String[] {"jj","dd","mm","bb","gg","aa"};

    String[] arr1 = new String[arr.length];
    
    String dest = "bb";
    boolean	isFlag = true;
    for (int i = 0; i < arr.length; i++) {
        if (dest.equals(arr[i])) {
            System.out.println("找到了指定的元素,位置为:" + i);
            isFlag = false;
            break;
        }
    }
    if (isFlag) {
        System.out.println("没有找到");
    }
}

5.2 二分法查找

实现思路:每次比较中间值,折半的方式检索

实用性:所要查找的数组必须有序

public static void main(String[] args) {
    String[] arr = new String[] {"jj","dd","mm","bb","gg","aa"};

    String[] arr1 = new String[arr.length];
    
    // 二分法查找 -- 前提:所要查找的数组必须有序
    int[] arr2 = new int[] {-98,-34,2,34,65,66,79,105,210,330};

    int dest1 = 2;
    int head = 0; // 初始的首索引
    int end = arr2.length - 1;// 初始的摸索引
    boolean isFlag1 = true;
    while (head <= end) {
        int middle = (head + end) / 2;
        if (dest1 == arr2[middle]) {
            System.out.println("找到了指定的元素,位置为:" + middle);
            isFlag1 = false;
            break;
        }else if (arr2[middle] > dest1) {
            end = middle - 1;
        }else {
            head = middle + 1;
        }
    }
    if (isFlag1) {
        System.out.println("没有找到");
    }
}

6.数组的排序

十大排序算法

  • 选择排序
    • 直接选择排序、堆排序
  • 交换排序
    • 冒泡排序、快速排序
  • 插入排序
    • 直接插入排序、折半插入排序、Shell排序
  • 归并排序
  • 桶式排序
  • 基数排序

理解

1)衡量排序算法的优劣

事件复杂度、空间复杂度、稳定性

2)排序的分类:内部排序 与 外部排序(需要借助于磁盘)

3)不同排序算法的时间复杂度

4)手写冒泡排序

public static void main(String[] args) {
    int[] arr = new int[] {43,32,96,-78,0,65,22,5,91,45};

    // 冒泡排序
    for (int i = 0; i < 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] + "\t");
    }
    System.out.println();

}

五、Arrays工具类

1.理解

  • 定义在java.util包下
  • Arrays:提供了很多操作数组的方法

基本使用

public static void main(String[] args) {
    // 1.boolean equals(int[] a,int[] b):判断两个数组是否相等
    int[] arr1 = new int[] {1,2,3,4};
    int[] arr2 = new int[] {1,3,2,4};
    boolean isEquals = Arrays.equals(arr1, arr2);
    System.out.println(isEquals);

    // 2.String toString(int[] a):输出数组信息
    System.out.println(Arrays.toString(arr1));

    // 3.void fill(int[] a, int val):将指定值填充到数组之中
    Arrays.fill(arr1, 10);
    System.out.println(Arrays.toString(arr1));

    // 4.void sort(int[] a):对数组进行排序
    Arrays.sort(arr2);
    System.out.println(Arrays.toString(arr2));

    // 5.int binarySearch(int[] a, int key):二分查找
    int[] arr3 = new int[] {43,32,96,-78,0,65,22,5,91,45};
    Arrays.sort(arr3);
    System.out.println(Arrays.toString(arr3));
    int index = Arrays.binarySearch(arr3,96);
    System.out.println(index);
}

六、数组的常见异常

1.数组角标越界异常:ArrayIndexOutOfBoundsException

		int[] arr = new int[] {1,3,5,7};
//		for (int i = 0; i < arr.length; i++) {
//			System.out.println(arr[i]);
//		}
//		System.out.println(arr[-2]);

2.空指针异常:NullPointerException

// 情况一
		int[] arr1 = new int[] {1,3,5,7};
		arr1 = null;
//		System.out.println(arr1[0]);
		
		// 情况二
		int[][] arr2 = new int[4][];
//		System.out.println(arr2[0][0]);
		
		// 情况三
		String[] arr3 = new String[] {"jj","kk","ss"};
//		arr3[0] = null;
		System.out.println(arr3[0].toString());

小知识:一旦程序出现异常,未处理时,就终止执行

posted on 2021-05-24 17:28  神秘杰尼龟  阅读(109)  评论(0)    收藏  举报