声明:本节内容为本人观看“遇见狂神说”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.冒泡排序
原理图:
- 冒泡排序就是将数组中相邻的两个元素做比较,如果大小不符合排序要求,则交换位置
- 每一轮遍历都会产生一个最大值或最小值,且下一轮遍历就不需要比较该值。
- 每一轮遍历都可以减少一次比较
- 依次循环,直到结束。
代码实现:
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
空指针异常。
空指针异常在内存图中的表现