数组:
1数组:
数组属于引用类型,数组的本质就是一个容器,存放一组相同数据类型变量的数据容器
2格式
数据类型[] 数组名; // Java语法
变式: 数据类型 数组名[]; // C语言
3数组的特点
(1)数组的本质
就是一个引用类型的变量,既然是一个变量就必须满足先声明再赋值再使用
(2)数组的初始化
*回顾变量初始化
a.声明: 告诉计算机开辟多大的内存空间
b.赋值: 找到变量所对应的内存地址,将数据保存到地址多标识的空间中去
c.使用: 通过地址找到空间,将数据取出,进行使用再重新保存到原空间中
**数组的初始化
a.声明: 告诉计算机开辟多大的连续内存空间
b.赋值:
c.使用:
(3) 数据类型相同
数组名实际就是一个变量,既然是变量就必须先赋值再使用
数组的每一个元素既可以是基本数据类型也可以是引用数据类型
(4)数组的内存分配
数据类型[] 数组名 = new 数据类型[长度];
(5)访问数组的元素
arr[下标/索引]
4异常
java.lang.NullPointerException
异常名称: 空指针异常
产生原因: 对象没有new就访问了对象的成员
解决办法: new
java.lang.ArrayIndexOutOfBoundsException
异常名称: 数组越界
产生原因: 访问了不在数组定义范围内的索引
解决办法: 检查索引是否超出了数组定义的范围
5数组的初始化
(1)静态初始化
格式一: 数据类型[] 数组名 = new 数据类型[] {元素1,元素2,元素3,...元素n};
格式二: 数据类型[] 数组名 = {元素1,元素2,元素3,...元素n};
(2) 动态初始化
格式:数据类型[] 数组名 = new 数据类型[长度];
注意:
有了格式二为什么还需要格式一: 格式一用作匿名对象(后面讲解面向对象讲解),格式二用作初始化
静态初始化和动态初始化的区别:
静态初始化在初始化的同时会给每一个元素赋值,不需要指定数组的长度,系统会自动根据元素的个数去动态计算数组的长度
动态初始化在初始化的同时由系统分配默认值,但是必须指定数组的长度
#数组的遍历
获取每一个元素
import java.util.Arrays;
/*
* 数组的遍历: 获取每一个元素
*
* 开闭原则: 对扩展开放,对修改关闭
*/
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arr;
arr = new int[] { 11, 22, 33, 44, 55 };
// arr[0] = 0.5;
// 方法一
// System.out.println(arr[0]);
// System.out.println(arr[1]);
// System.out.println(arr[2]);
// System.out.println(arr[3]);
// System.out.println(arr[4]);
// System.out.println(arr[5]);
System.out.println("=========================");
// 方法二:利用循环改进
// for (int i = 0; i < 6; i++) {
// System.out.println(arr[i]);
// }
System.out.println("=========================");
// System.out.println(arr.length);
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
// printArray(arr);
// System.out.println(arrayToString(arr));
System.out.println(Arrays.toString(arr));
}
/*
* 功能: 遍历数组
* 返回值类型: void
* 参数列表: int[] arr
* 方法名: printArray
*/
// 方法三
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void printArray(double[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
/*
* [11, 22, 33, 44, 55]
* 功能: 遍历数组
* 返回值类型: String
* 参数列表: int[] arr
* 方法名: arrayToString
*
* 思路:
* 1.拼接[
* 2.遍历数组获取到每一个元素
* 3.拼接元素
* 如果是最后一个元素,只拼接元素
* 否则拼接元素 + ", "
* 4.拼接]
*/
public static String arrayToString(int[] arr) {
String result = "";
// 1.拼接[
result += "["; // result = result + "[";
// 2.遍历数组获取到每一个元素
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
// 如果是最后一个元素,只拼接元素
result += arr[i];
} else {
// 否则拼接元素 + ", "
result += arr[i] + ", ";
}
}
// 4.拼接]
result += "]";
return result;
}
}
6数组最大值
/*
* 功能: 求出最大值。 返回值类型: int 参数列表: int[] arr 方法名: getMaxValue
*
* 1.假设第一个数为最大值 2.让第一个数和后面每一个数进行比较 3.如果发现后面有一个数大于这个假定的最大值 4.那么就将这个数设置为假定的最大值
* 5.循环结束之后,最大值就出来
*/
public static int getMaxValue(int[] arr) {
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
public static int getMinValue(int[] arr) {
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
7数组的倒置
/*
* 功能: 将数组倒置并输出
* 返回值类型: void
* 参数列表: int[] arr
* 方法名: reverseArray
*
* 11, 22, 33, 44, 55 第一个数和最后一个数交换位置
* arr[0] arr[arr.length - 1 - 0] int temp = 0;
* temp = arr[0];
* arr[0] = arr[arr.length - 1 - 0];
* arr[arr.length - 1] =temp;
* 第二个数和倒数第二个数交换位置
* arr[1] arr[arr.length - 1 - 1] int temp = 0;
* temp =arr[1]; arr[1] = arr[arr.length - 1 - 1];
* arr[arr.length - 1 - 1] = temp;
*
* arr[2] arr[arr.length - 1 - 2] 交换的次数 如果arr.length = 5, 交换2次 如果arr.length = 6,
* 交换3次 如果arr.length = 7, 交换3次 如果arr.length = 8, 交换4次 i arr.length / 2次
*/
public static void reverseArray(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = 0;
temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
}
8数组的查找
(1)数组的基本查找
/*
* E 数组查找 猜数游戏:从键盘中任意输入一个数据,判断数列中是否包含此数。
* 返回值类型: boolean
* 参数列表: int[] arr, int num
* 方法名: basicSearch
*/
public static boolean basicSearch(int[] arr, int num) {
boolean flag = false;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num) {
flag = true;
break;
}
}
return flag;
}
public static int basicSearch2(int[] arr, int num) {
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num) {
index = i;
break;
}
}
return index;
}
}
(2)二分法查找
/*
* 二分法查找
* 返回值类型: int
* 参数列表: int[] arr, int num
* 方法名: binarySearch
*/
public static int binarySearch(int[] arr, int num) {
// 1.定义最小索引和最大索引
int min = 0;
int max = arr.length - 1;
// 2.计算中间索引
int mid = (min + max) / 2;
while (arr[mid] != num) {
/*
* 中间索引所对应的数值 > num 左边找
* 中间索引所对应的数值 < num 右边找
*/
if (arr[mid] > num) {
max = mid - 1;
} else if (arr[mid] < num) {
min = mid + 1;
}
if (min > max) {
return -1;
}
mid = (min + max) / 2;
}
// 返回中间索引
return mid;
}
}
(3)冒泡排序法
规律:
* 1.相邻两个数进行比较,大的数冒泡,交换两个数的位置
* 2.一共比较了arr.length - 1趟
* 3.每一趟比上一趟少比较1次
*/
public class ArrayDemo08 {
public static void main(String[] args) {
int[] arr = {24, 69, 80, 55, 13};
System.out.println("冒泡排序前:" + Arrays.toString(arr));
// 第一趟排序
/*
* arr[0] arr[1] 比较
* arr[1] arr[2] 比较
* arr[2] arr[3] 比较
* arr[3] arr[4] 比较
*
* 如果左边的大于右边的就交换两个数的位置
* 一共比较了4次
*/
/*for (int i = 0; i < arr.length - 1 - 0; i++) {
if (arr[i] > arr[i+1]) {
int temp = 0;
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第一趟排序后:" + Arrays.toString(arr));
for (int i = 0; i < arr.length - 1 - 1; i++) {
if (arr[i] > arr[i+1]) {
int temp = 0;
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第二趟排序后:" + Arrays.toString(arr));
for (int i = 0; i < arr.length - 1 - 2; i++) {
if (arr[i] > arr[i+1]) {
int temp = 0;
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第三趟排序后:" + Arrays.toString(arr));
for (int i = 0; i < arr.length - 1 - 3; i++) {
if (arr[i] > arr[i+1]) {
int temp = 0;
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第四趟排序后:" + Arrays.toString(arr));*/
System.out.println("=========================");
/*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 = 0;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}*/
bubbleSort(arr);
System.out.println("冒泡排序后:" + Arrays.toString(arr));
}
public static void bubbleSort(int[] arr) {
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 = 0;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
9foreach 数组/集合专用遍历器
foreach遍历数组
集合和数组专属遍历方式,底层还是使用普通for遍历
格式:
for(数据类型 变量名: 数组名/集合名){
}
普通for和foreach的区别
1.简化了遍历
2.没有索引
public class ArrayDemo11 {
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
for(int i : arr) {
System.out.println(i);
}
}
}
10可变参数
针对参数类型相同但是参数的个数不同的情况非常方便
可变参数: 是一种形参类型,本质就是数组,用来接收个数不同但是类型相同的多个参数
可变参数的格式: 数据类型… 参数名
可变参数的注意事项
1.可变参数本质是数组
2.可变参数的…可以放在参数类型和变量名中间的任意位置
3.可变参数必须出现参数列表的最后面
public class ArrayDemo12 {
public static void main(String[] args) {
// System.out.println(add(10, 20)); // [I@7852e922
// System.out.println(add(10, 20, 30));
// System.out.println(add(10, 20, 30, 40));
int[] arr = {11, 22, 33, 44};
int[] arr2 = {55,66};
add(arr, arr2);
}
// public static int add(int... args) {
System.out.println("我是可变参数的方法");
System.out.println(args);
// int sum = 0;
// for(int i : args) {
// sum += i;
// }
// return sum;
// }
// public static int add(double d, int... args) {
System.out.println("我是可变参数的方法");
System.out.println(args);
// int sum = 0;
// for(int i : args) {
// sum += i;
// }
// return sum;
// }
public static int add(int[]... args) {
// System.out.println("我是可变参数的方法");
// System.out.println(args);
// int sum = 0;
// for(int i : args) {
// sum += i;
// }
// return sum;
System.out.println(args);
return 0;
}
public static void show(String... args) {
}
// 计算两个数的和
// public static int add(int a, int b) {
// System.out.println("ArrayDemo12.add(a,b)");
// return a + b;
// }
//
// // 计算三个数的和
// public static int add(int a, int b, int c) {
// System.out.println("ArrayDemo12.add(a,b,c)");
// return a + b + c;
// }
//
// public static int add(int a, int b, int c, int d) {
// System.out.println("ArrayDemo12.add(a,b,c,d)");
// return a + b + c + d;
// }
}
11 Arrays数组工具类
ublic class ArrayDemo03 {
public static void main(String[] args) {
int[] arr = {22, 11, 66, 88, 99, 44};
// Arrays的遍历输出方法
System.out.println(Arrays.toString(arr));
// Arrays的排序方法
// Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// Arrays的二分法查找方法
int index = Arrays.binarySearch(arr, 88);
System.out.println(index);
// System的arraycopy方法,这是一个本地方法,底层不由Java实现,由C语言实现
int[] dest = {100, 200, 300};
// Object src, int srcPos,Object dest, int destPos, int length
System.arraycopy(arr, 1, dest, 0 ,3);
System.out.println(Arrays.toString(dest));
// 复制数组
int[] newArr = Arrays.copyOf(arr, arr.length);
System.out.println(Arrays.toString(newArr));
// 数组扩容
int[] newArr2 = Arrays.copyOf(arr, arr.length + 1);
System.out.println(Arrays.toString(newArr2));
// 缩小数组的容量
int[] newArr3 = Arrays.copyOf(arr, arr.length - 2);
System.out.println(Arrays.toString(newArr3));
// 填充数组
// Arrays.fill(arr, 100);
// System.out.println(Arrays.toString(arr));
// 填充数组的一部分 左闭右开原则
// Arrays.fill(arr, 2, 4, 100);
// System.out.println(Arrays.toString(arr));
int[] copyArr = Arrays.copyOfRange(arr, 2, 5);
System.out.println(Arrays.toString(copyArr));
int[] arr1 = {11, 22, 33, 44};
int[] arr2 = {11, 22, 33, 44};
System.out.println(Arrays.equals(arr1, arr2));
}
}
12数组的动态扩容
package com.sxt.arraydemo;
import java.util.Arrays;
/*
* 数组的扩容和缩容
* 动态扩容
* 1.使用for循环复制元素扩容
* 缺陷: 拷贝一部分元素需要计算索引,比较复杂
* 2.System.arracopy()扩容
* 缺陷: 拷贝数组的一部分到目标数组,如果长度超过了目标数组的索引,会抛出异常
* 3.Arrays.copyOf扩容
* 观察copyOf方法的源码:
* public static int[] copyOf(int[] original, int newLength) {
* int[] copy = new int[newLength];
* System.arraycopy(original, 0, copy, 0,
* Math.min(original.length, newLength));
* return copy;
* }
* 4.利用Object类中一个 clone 方法,该方法是真正意义上的复制数组
*/
public class ArrayDemo04 {
public static void main(String[] args) {
int[] src = { 11, 22, 33, 44 };
int[] desc = new int[10];
// 1.使用for循环复制元素扩容
// for (int i = 0; i < src.length; i++) {
// desc[i] = src[i];
// }
// System.out.println(Arrays.toString(desc));
// 2.System.arracopy()扩容
// System.arraycopy(src, 0, desc, 7, src.length); // 数组越界
// System.out.println(Arrays.toString(desc));
// 3.Arrays.copyOf扩容
int[] descArr = Arrays.copyOf(src, src.length + 5);
System.out.println(Arrays.toString(descArr));
}
}
13数组的增删查改
实现的功能:
增加add 插入 insert 删除 delete 修改 update 查询 get
package com.sxt.arraydemo;
import java.util.Arrays;
/*
* 自定义工具类 MyArrays
*/
public class MyArrays {
static int[] srcArr;
public static void main(String[] args) {
int[] arr = {11,22,33,44,55};
setArr(arr);
System.out.println("源数组: " + Arrays.toString(srcArr));
add(66);
System.out.println("add: " + Arrays.toString(srcArr));
insert(2, 88);
System.out.println("insert: " + Arrays.toString(srcArr));
delete(5);
System.out.println("delete: " + Arrays.toString(srcArr));
update(0, 100);
System.out.println("update: " + Arrays.toString(srcArr));
System.out.println("get: " + get(0));
}
/*
* 功能: 用于外界传入一个数组来初始化我这个全局变量的数据
* 返回值类型: void
* 参数列表: int[] arr;
* 方法名: setArr
*/
public static void setArr(int[] arr) {
srcArr = arr;
}
/*
* 功能: 在数组的末尾添加一个元素
* 返回值类型: void
* 参数列表: int num
* 方法名: add
* 1.创建一个新的数组,长度+1
* 2.将源数组的元素全部复制到目标数组中
* 3.在目标数组的末尾添加元素
* 4.地址传递
*/
public static void add(int num) {
int[] descArr = Arrays.copyOf(srcArr, srcArr.length + 1);
descArr[descArr.length - 1] = num;
srcArr = descArr;
}
/*
* 功能: 在数组的指定索引位置插入一个元素
* 返回值类型: void
* 参数列表: int index, int num
* 方法名: insert
* 1.创建一个新的数组,长度+1
* 2.插入位置前面的元素原封复制到目标数组中
* 3.将num这个元素插入到索引位置
* 4.将索引后面的元素复制到目标数组
* 5.地址传递
*/
public static void insert(int index, int num) {
int[] descArr = new int[srcArr.length + 1];
System.arraycopy(srcArr, 0, descArr, 0, index);
descArr[index] = num;
System.arraycopy(srcArr, index, descArr, index + 1, srcArr.length - index);
srcArr = descArr;
}
/*
* 功能: 在数组的指定索引位置删除一个元素
* 返回值类型: void
* 参数列表: int index
* 方法名: delete
* 1.创建一个新的数组,长度-1
* 2.删除位置前面的元素原封复制到目标数组中
* 3.将源数组索引后面的元素覆盖复制到目标数组中
* 4.地址传递
*/
public static void delete(int index) {
int[] descArr = new int[srcArr.length - 1];
System.arraycopy(srcArr, 0, descArr, 0, index);
System.arraycopy(srcArr, index + 1, descArr, index, descArr.length - index);
srcArr = descArr;
}
/*
* 修改数组中对应索引的元素
* 返回值类型: void
* 参数列表: int index, int num
* 方法名: update
*/
public static void update(int index, int num) {
srcArr[index] = num;
}
/*
* 查询数组中对应索引的元素
* 返回值类型: int
* 参数列表: int index
* 方法名: get
*/
public static int get(int index) {
return srcArr[index];
}
}
14多维数组
/*
* 多维数组本质也是一维数组
* 二维数组
* 本质就是存放了一维数组的数组
*
* 格式1:
* 数据类型[] 数组名 = new 数据类型[数组的长度];
* 数据类型[][] 数组名 = new 数据类型[m][n];
* m: 二维数组中一维数组的长度。m必不可少
* n: 每一个一维数组中元素的个数。n可以省略
*
* int[][] arr = new int[3][2];
* 表示arr中有3个一维数组,每一个一维数组有2个元素
*
* 变式:
* 数据类型 数组名[][] = new 数据类型[m][n];
* 数据类型[] 数组名[] = new 数据类型[m][n];
*
* 面试题:
* int[] x,y[],z[][]; 表示1个一维数组,1一个二维数组,1个三维数组
*
* int[] x;
* int[] y[];
* int[] z[][];
*
* 格式2:
* 数组类型[][] 数组名 = new 数据类型[m][];
* m: 二维数组中一维数组的长度
* n: m必不可少,n可省略,表示每一个一维数组的元素个数不确定
* 可以后期动态地改变每一个一维数组元素的个数
*
* int a=2,b=2,c;
*/
public class TwoArrayDemo01 {
public static void main(String[] args) {
int[][] arr = new int[3][2];
int[] arr2[] = new int[3][3];
int[] x,y[],z[][]; // 1
int n[] = new int[2],i,j,k;
/*
* int n[] = new int[2];
* int i;
* int j;
* int k;
*/
}
}
(1)访问二维数组的格式:
*格式一:
数据类型[][] 数组名 = new 数据类型[m][n];
注意: m必不可少,n可省略
数组名[m][n];
public class TwoArrayDemo02 {
public static void main(String[] args) {
int[][] arr = new int[3][2];
System.out.println(arr); // 地址 [[I@7852e922
System.out.println(arr[0]); // 地址 [I@4e25154f
System.out.println(arr[1]); // 地址 [I@70dea4e
System.out.println(arr[2]); // 地址 [I@5c647e05
// System.out.println(arr[3]); // 数组越界
System.out.println(arr[0][0]); // 0
System.out.println(arr[0][1]); // 0
System.out.println(arr[1][0]); // 0
// System.out.println(arr[1][2]); // 数组越界
arr[0][0] = 100;
arr[0][1] = 200;
arr[1][0] = 300;
System.out.println(arr[0][0]); // 100
System.out.println(arr[0][1]); // 200
System.out.println(arr[1][0]); // 300
}
}
**格式二:
二维数组的格式2的内存图
数据类型[][] 数组名 = new 数据类型[m][];
public class TwoArrayDemo03 {
public static void main(String[] args) {
int[][] arr = new int[3][];
System.out.println(arr); // 地址
arr[0] = new int[3];
arr[1] = new int[2];
arr[2] = new int[1];
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[0][0]); // 0
System.out.println(arr[0][1]); // 0
System.out.println(arr[1][0]); // 0
// System.out.println(arr[1][2]); // 数组越界
arr[0][0] = 100;
arr[0][1] = 200;
arr[1][0] = 300;
arr[2][0] = 400;
System.out.println(arr[0][0]); // 100
System.out.println(arr[0][1]); // 200
System.out.println(arr[1][0]); // 300
System.out.println(arr[2][0]); // 400
}
}
(2)二维数组的静态初始化
二维数组的静态初始化
public class TwoArrayDemo04 {
public static void main(String[] args) {
int[][] arr = {{11,22,33}, {44,55}, {66,77,88,99}};
// 遍历第一个一维数组
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[0][2]);
for (int i = 0; i < arr[0].length; i++) {
System.out.println(arr[0][i]);
}
// 遍历第二个一维数组
System.out.println(arr[1][0]);
System.out.println(arr[1][1]);
for (int i = 0; i < arr[1].length; i++) {
System.out.println(arr[1][i]);
}
// 遍历第三个一维数组
System.out.println(arr[2][0]);
System.out.println(arr[2][1]);
System.out.println(arr[2][2]);
System.out.println(arr[2][3]);
for (int i = 0; i < arr[2].length; i++) {
System.out.println(arr[2][i]);
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}
}
}