一、概述
①是多个相同类型数据按照一定的顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理
②常见概念:
|-数组名
|-下标或索引
|-元素
|-数组长度:元素的个数
③特点:
|-有序排列
|-属于引用数据类型的变量,而数组中的元素可以是基本数据类型,也可以是引用数据类型
|-创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块块连续空间的首地址
|-数组的长度一旦确定,就不能修改
|-可以通过下标(或索引)的方式调用指定位置的元素,速度很快
④分类:
|-按照维度:一维数组、二维数组、三维数组
|-按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)
二、一维数组的使用
①一维数组的声明和初始化
|-静态初始化:数组的初始化和数组元素的赋值操作同时进行
|-动态初始化:数组的初始化和数组元素的赋值操作分开进行
例:
package com.atguigu.java;
public class ArrayTest {
public static void main(String[] args) {
int num;//声明
num = 10;//初始化
int id = 1001;//声明+初始化
int[] ids;
//静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[] {1001,1002,1003,1004};
//动态初始化:数组的初始化和数组元素的赋值操作分开进行
String [] names = new String[5];
}
}
总结:
|-数组一旦初始化完成,其长度就确定了
②调用数组的指定位置的元素:可以通过下标(或索引)的方式
|-数组的角标(或索引)从0开始的,到数组的长度-1结束
例:
package com.atguigu.java;
public class ArrayTest {
public static void main(String[] args) {
//调用数组的指定位置的元素:可以通过下标(或索引)的方式
String [] names = new String[5];
names[0] = "王明";
names[1] = "王赫";
names[2] = "张学良";
names[3] = "孙居龙";
names[4] = "王宏志";
}
}
③数组的长度与遍历,属性:length
例:
package com.atguigu.java;
public class ArrayTest {
public static void main(String[] args) {
String [] names = new String[5];
//调用数组的指定位置的元素:可以通过下标(或索引)的方式
names[0] = "王明";
names[1] = "王赫";
names[2] = "张学良";
names[3] = "孙居龙";
names[4] = "王宏志";
//获取数组长度
System.out.println(names.length);
//遍历数组
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
}
}
④数组元素的默认初始化值
|-数组元素是整型:0
|-数组元素是浮点型:0.0
|-数组元素是char型:0或‘\u0000’非‘0’
|-数组元素是boolean型:false
|-数组元素是引用数据类型:null
例:
package com.atguigu.java;
public class ArrayTest2 {
public static void main(String[] args) {
int [] arr = new int[4];
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("******************");
short [] arr1 = new short[4];
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
System.out.println("******************");
float [] arr2 = new float[5];
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
System.out.println("*****************");
char [] arr3 = new char[4];
for (int i = 0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
if(arr3[0] == 0) {
System.out.println("你好!");
}
System.out.println("***************");
boolean [] arr4 = new boolean[4];
for (int i = 0; i < arr4.length; i++) {
System.out.println(arr4[i]);
}
System.out.println("***************");
String [] arr5 = new String[5];
for (int i = 0; i < arr5.length; i++) {
System.out.println(arr5[0]);
if(arr5[0] == null) {
System.out.println("山西天气不错!");
}
}
}
}
⑤数组的内存解析
例:输出电话号码
public class Rent {
public static void main(String[] args) {
int[] arr = new int[] { 8, 2, 1, 0, 3 };
int[] index = new int[] { 2, 0, 3, 2, 4, 0, 1, 3, 2, 3, 3 };
String tel = "";
for (int i = 0; i < index.length; i++) {
tel += arr[index[i]];
}
System.out.println("联系方式:" + tel);
}
}
例:输出学生成绩
package com.atguigu.java;
import java.util.Scanner;
public class ArrayDemo {
public static void main(String[] args) {
//读取学生个数
Scanner scan = new Scanner(System.in);
System.out.println("请输入学生人数:");
int number = scan.nextInt();
//创建数组,存储学生成绩
int [] scores = new int[number];
//给数组中的元素赋值
System.out.println("请输入"+number+"个成绩:");
int maxScore = 0;
for (int i = 0; i < scores.length; i++) {
scores[i] = scan.nextInt();
if(maxScore < scores[i]) {
maxScore = scores[i];
}
}
//根据每个学生成绩与最高分的差值,得到每个学生的等级,并输出等级和成绩
char level;
for (int i = 0; i < scores.length; i++) {
if(maxScore - scores[i] <= 10) {
level = 'A';
}else if(maxScore - scores[i] <= 20) {
level = 'B';
}else if(maxScore - scores[i] <= 30) {
level = 'C';
}else {
level = 'D';
}
System.out.println("student" + i + "score is" + scores[i]+"grade is" + level);
}
}
}
三、二维数组的使用
|-可以看成是一维数组array1又作为另一个一维数组array2的元素而存在,从数组底层的运行机制来看,其实没有多维数组
①二维数组的声明和初始化
例:
package com.atguigu.java;
public class ArrayTest3 {
public static void main(String[] args) {
//二维数组的声明和初始化
//静态初始化
int [] [] arr = 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 [] srr5[] ={{1,2,3},{4,5},{6,7,8}};
}
}
②调用二维数组的指定位置元素
例:
package com.atguigu.java;
public class ArrayTest3 {
public static void main(String[] args) {
//二维数组的声明和初始化
//静态初始化
int [] [] arr = new int[] []{{1,2,3},{4,5},{6,7,8}};
//动态初始化1:
String [][] arr2 = new String [3][2];
//动态初始化2:
String [][] arr3 = new String [3][];
//调用二维数组的指定位置元素
System.out.println(arr[0][1]);//2
System.out.println(arr2[1][1]);//null
arr3[1] =new String[4];
System.out.println(arr3[1][0]);
}
}
③二维数组的长度获取
例:
package com.atguigu.java;
public class ArrayTest3 {
public static void main(String[] args) {
int [] arr4[] = new int[] [] {{1,2,3},{4,5},{6,7,8}}
//二维数组的长度获取
System.out.println(arr4.length);//3
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//2
}
}
④二维数组遍历
例:
package com.atguigu.java;
public class ArrayTest3 {
public static void main(String[] args) {
int [] arr4[] = new int[] [] {{1,2,3},{4,5},{6,7,8}};
//二维数组的遍历
for (int i = 0; i < arr4.length; i++) {
for (int j = 0; j < arr4[i].length; j++) {
System.out.print(arr4[i][j] + " ");
}
}
}
}
⑤二维数组元素默认初始化值
方式一:
int [][] arr = new int[4][3];
方式二:
int [][] arr = new int[4][];
外层元素的初始化值为:null
内层元素的初始化值为:不能调用,否则报错
⑥二维数组内存解析
四、多维数组的使用
例:求和
package com.atguigu.java;
public class ArryExer1 {
public static void main(String[] args) {
int [][] arr = new int[][] {{3,5,8},{12,9},{7,0,6,4}};
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);
}
}
例:杨辉三角
package com.atguigu.java;
public class YangHuiTest {
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();
}
}
}
五、数组中涉及的常见算法
例:赋一些随机整数,求最大值、最小值、平均数、总和
package com.atguigu.java;
public class ArrayTest1 {
public static void main(String[] args) {
int [] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random() * (99 - 10 + 1) + 10);
}
//最大值
int maxValue = arr[0];
for (int i = 0; i < arr.length; i++) {
if(maxValue < arr[i]) {
maxValue = arr[i];
}
}
System.out.println("最大值为:" + maxValue);
//最小值
int minValue = arr[0];
for (int i = 0; i < arr.length; i++) {
if(minValue > arr[i]) {
minValue = arr[i];
}
}
System.out.println("最小值为:" + minValue);
//总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("总和为:" + sum);
//平均数
int avgValue = sum / arr.length;
System.out.println("平均数为:" + avgValue );
}
}
例:数组赋值
package com.atguigu.java;
public class ArrExer2 {
public static void main(String[] args) {
int [] array1,array2;
array1 = new int[] {2,3,5,7,11,13,17,19};
//显示array1的内容
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " \t");
}
//赋值array2变量等于array1
//不能称作数组的复制
array2 = array1;
//修改array2中的偶索引元素,使其等于索引值(如:array[0] = 0,array[2] = 2)
for (int i = 0; i < array2.length; i++) {
if(i % 2 == 0) {
array2[i] = i;
}
}
System.out.println();
//打印出array1
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " \t");
}
}
}
例:数组复制实现代码
package com.atguigu.java;
public class ArrayTest2 {
public static void main(String[] args) {
String [] arr = new String[] {"JJ","DD","MM","BB","GG","AA"};
//数组的复制(区别于数组变量的赋值:arr1 = arr)
String [] arr1 = new String[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
}
}
例:使用数组复制
package com.atguigu.java;
public class ArrayExer3 {
public static void main(String[] args) {
int [] array1,array2;
array1 = new int[] {2,3,5,7,11,13,17,19};
//显示array1的内容
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " \t");
}
//数组的复制
array2 = new int[array1.length];
for (int i = 0; i < array2.length; i++) {
array2[i] = array1[i];
}
//修改array2中的偶索引元素,使其等于索引值(如:array[0] = 0,array[2] = 2)
for (int i = 0; i < array2.length; i++) {
if(i % 2 == 0) {
array2[i] = i;
}
}
System.out.println();
//打印出array1
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " \t");
}
}
}
例:数组元素的反转
package com.atguigu.java;
public class ArrayTest2 {
public static void main(String[] args) {
String [] arr = new String[] {"JJ","DD","MM","BB","GG","AA"};
//数组的复制(区别于数组变量的赋值:arr1 = arr)
String [] arr1 = new String[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
//数组的反转
// //方法一:
// for (int i = 0; i < arr1.length / 2; i++) {
// String temp = arr[i];
// arr[i] = arr[arr.length - i - 1];
// arr[arr.length - i - 1] = temp;
// }
//方法二:
for (int i = 0 , j = arr.length - 1;i < j; i++,j--) {
String temp = arr[i];
arr[i]=arr[j];
arr[j] = temp;
}
//遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " \t");
}
}
}
例:线性查找
package com.atguigu.java;
public class ArrayTest2 {
public static void main(String[] args) {
String [] arr = new String[] {"JJ","DD","MM","BB","GG","AA"};
//数组的复制(区别于数组变量的赋值:arr1 = arr)
String [] arr1 = new String[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
//遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " \t");
}
System.out.println();
//查找(或搜索)
//线性查找
String dest = "CC";
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("没有找到!");
}
}
}
例:二分法查找
package com.atguigu.java;
public class ArrayTest2 {
public static void main(String[] args) {
//二分法查找
//前提:索要查找的数组必须有序
int [] arr2 = new int[] {-98,-34,2,34,54,66,79,105,210,333};
int dest1 = -98;
int head = 0;//初始首索引
boolean isFlag1 = true;
int end =arr2.length - 1;//初始末索引
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 {//arr2[middle] < dest1
head = middle + 1;
}
}
if(isFlag1) {
System.out.println("很遗憾,没有找到");
}
}
}
算法的五大特征:
例:冒泡排序
package com.atguigu.java;
public class BubbleSortTest {
public static void main(String[] args) {
int [] arr = new int [] {43,32,76,-98,0,64,33,-21,32,99};
//冒泡排序
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");
}
}
}
排序算法性能对比:
六、Arrays工具类的使用
①java.util.Arrays:操作数组的工具类,包含了用来操作数组(比如:排序和搜索)的各种方法
例:
package com.atguigu.java;
import java.util.Arrays;
public class ArraysTest {
public static void main(String[] args) {
//1.
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.
System.out.println(Arrays.toString(arr1));
//3.
Arrays.fill(arr1, 10);
System.out.println(Arrays.toString(arr1));
//4.
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//5.
int [] arr = new int [] {43,32,76,-98,0,64,33,-21,32,99};
int index = Arrays.binarySearch(arr, 10);
//System.out.println(index);
if (index > 0) {
System.out.println("存在");
}else {
System.out.println("不存在");
}
}
}
七、数组使用中的常见异常
①数组角标越界异常:ArrayIndexOutOfBoundsException
package com.atguigu.java;
public class ArrayException {
public static void main(String[] args) {
//①数组角标越界异常:ArrayIndexOutOfBoundsException
int [] arr = new int [] {1,2,3,4,5};
for (int i = 0; i <= arr.length; i++) {
System.out.println(arr[i]);
}
// System.out.println(arr[-2]);
}
}
②空指针异常:NullPointerException
package com.atguigu.java;
public class ArrayException {
public static void main(String[] args) {
int [] arr = new int [] {1,2,3,4,5};
//情况一:
//int [] arr1 = new int [] {};
//arr1 = null;
//System.out.println(arr1[0]);
//情况二:
//int [] [] arr2 =new int[4][];
//System.out.println(arr2[0][0]);
//情况三:
String [] arr3 =new String [] {"AA","BB","CC"};
arr3[3] = null;
System.out.println(arr3[0].toString());
}
}