一、数组
1.数据结构
概念:计算机保存和组织数据的一种方式,保存方式不同,带来的操作性能不同
注:合理选择数据结构会有效的提升程序的存储效率和运行效率
2.数组特性
数组:连续存储,确定长度后不能修改,下标从0开始,可以用.length查看数组个数
优点:查询修改效率极高
缺点:添加删除效率较低(因为需要频繁地创建控件和数据移动)
在Java中数组是没有添加和删除操作的,需要自己编写代码
3.数组声明
3.1.静态声明
在已知每个元素值的时候使用静态声明
声明方式:
数据类型[] 变量名 = {值,值,值…};//简写版
数据类型 变量名[] = {值,值,值…};
int[] arr1 = {1,2,3,4,5};
int arr2[] = {1,2,3,4,5};
数据类型[] 变量名 = new 数据类型[]{值,值,值…}//完全体
int[] arr3 = new int[]{1,2,3,4,5};
3.2.动态声明
不知道每个元素值的时候使用动态声明
声明方式:
数据类型[] 变量名 = new 数据类型[长度];
int[] arr4 = new int[4]
;
注:动态声明中保存的都是和数组数据类型对应的默认值
整数:0 ,小数:0.0 ,布尔型:false ,字符:\u0000 ,引用:null
4.内存中储存方式
数组是引用类型,所以保存在堆内存中,栈内存只是存储了堆内存的内存地址
5.数组使用
5.1.获取数据
通过查询数组[下标]来获取数组数据,
例如:
int[] arr1 = new int[]{1,2,3,4,5};
System.out.println(arr3[0]);// 1
5.2.更改数据
修改: 数组[下标] = 值;
arr2[0] = 1
5.3.遍历
5.3.1.获取数组长度
数组.length
arr[3].length
5.3.2.遍历数组
for (int i = 0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
5.4.常见错误/异常
下标越界异常,例:
java.lang.ArrayIndexOutOfBoundsException: 22
当下标小于0 或 大于等于length的时候 就会出现下标越界情况
5.5.数组传递
public class Array_05 {
public static void main(String[] args) {
int i = 2;
// 传入变量
m2(i);
// 传入字面量
m2(22);
int[] arr1 = { 1, 2, 3, 4 };
// 当调用一个方法,并且需要传入数组的时候
// 1 传递的是已经创建好的数组
m1(arr1);
// 2 传递字面量
m1(new int[]{ 1, 2, 3, 4 });
}
public static void m2(int i) {}
public static void m1(int[] arr) {}
}
5.6.给main方法传参(一般不会出现)
6.传值和传址
传值(8种基本数据类型)和传址(3种引用数据类型)
public class Array_06 {
public static void main(String[] args) {
// 基本
int age = 18;
m1(age);
System.out.println("main : " + age);
// 引用
int[] ages = {11,12,13};
m2(ages);
System.out.println("main : "+ages[0]);
}
// 引用类型传递
public static void m2(int[] ages) {
ages[0] = 21;
System.out.println("m2 : "+ages[0]);
}
// 基本类型传递
public static void m1(int age) {
age--;
System.out.println("m1 : " + age);
}
}
7.数组替换复制
public class Array_07 {
public static void main(String[] args) {
int[] src = { 1, 2, 3, 4, 5, 6 };
int[] dest = { 11, 12, 13, 14, 15, 16 };
int srcIndex = 1;
int destIndex = 2;
int length = 2;
// copy(src, srcIndex, dest, destIndex, length);
// 调用API
System.arraycopy(src, srcIndex, dest, destIndex, length);
for (int i = 0; i < dest.length; i++) {
System.out.println(dest[i]);
}
}
/**
* 替换复制
*
* @param src
* 源数组
* @param srcIndex
* 源数组起始位置
* @param dest
* 目标数组
* @param destIndex
* 目标数组起始位置
* @param length
* 复制个数
*/
public static void copy(int[] src, int srcIndex, int[] dest, int destIndex,
int length) {
for (int i = 0; i < length; i++) {
dest[destIndex] = src[srcIndex];
srcIndex++;
destIndex++;
}
}
}
8.数组插入复制
public class Array_08 {
public static void main(String[] args) {
int[] src = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
int[] dest = {11,12,13,14,15,16,17,18,19,20,21,22,23,24};
int srcIndex = 2;
int destIndex = 3;
int length = 3;
int[] newDest = copy(src, srcIndex, dest, destIndex, length);
for (int i = 0; i < newDest.length; i++) {
System.out.println(newDest[i]);
}
}
/**
* 插入复制
*
* @param src
* 源数组
* @param srcIndex
* 源数组起始位置
* @param dest
* 目标数组
* @param destIndex
* 目标数组起始位置
* @param length
* 复制个数
*/
public static int[] copy(int[] src, int srcIndex, int[] dest,
int destIndex, int length) {
// 新数组长度 = 目标数组长度 +插入个数
int[] newDest = new int[dest.length + length];
// 1 把目标数组中,0~起始索引的数据先放到新数组中
for (int i = 0; i <= destIndex; i++) {
newDest[i] = dest[i];
}
// 2 把源数组中,起始位置开始,到 起始位置+length结束
// 放到新数组中
int index = destIndex+1;
for (int i = srcIndex; i < srcIndex+length; i++) {
newDest[index]=src[i];
index++;
}
// 3 把目标数组中,剩余数据放到新数组中
// destIndex+1开始 到 dest.length 结束
// 放到index开始
for (int i = destIndex+1; i < dest.length; i++) {
newDest[index] = dest[i];
index++;
}
return newDest;
}
}
二、二维数组
1.声明方式(与一维数组类似)
1.1.静态声明
数据类型[][] 数组名 = {};
int[][] arr1 = {{1,2,3},{1,2,3},...};
数据类型[][] 数组名 = new 数据类型{};
int[][] arr1 = new int[][]{{1,2,3},{1,2,3},...};
1.2.动态声明
数据类型[][] 数组名 = new 数据类型[n][m];
int[][] arr1 = new int[2][2];
2.内存中存储方式
3.使用方式(与一维数组类似)
3.1.获取数据
public class Array_03 {
public static void main(String[] args) {
// 声明
int[][] arr = { { 1, 2, 3 }, { 2, 3, 4 }, { 3, 4, 3, 6, 8, 9, 5 } };
int[][] arr1 = new int[][] { { 1, 2, 3 }, { 2, 3, 4 } };
int[][] arr2 = new int[5][3];
// 查询
int[] arr_0 = arr[0];
int arr_00 = arr_0[0];
System.out.println(arr_00);
// 数组[下标][下标]
// 第一个下标 是查询哪个一维数组
// 丁二下标 是查询一维数组中哪个元素
System.out.println(arr[0][0]);
// 最后一个数据
System.out.println(arr[2][6]);
int[] arr_2 = arr[arr.length - 1];
int arr_26 = arr_2[arr_2.length - 1];
System.out.println(arr_26);
System.out.println(arr[arr.length - 1][arr[arr.length - 1].length - 1]);
}
}
3.2.更改数据
二维数组第一个值的下标为[0][0];
修改数组中的第一个值为66:
arr[0][0] = 66;
3.3.遍历
arr = new int[5][5];
arr[3][1]=1;
for (int i = 0; i < arr.length; i++) {
// int[] arr_i = arr[i];
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
3.4.动态声明锯齿状
类似九九乘法表,不过二维数组是要单独初始化每一个一维数组的长度,也就是动态声明二维数组
public class Array_03 {
public static void main(String[] args) {
// 动态声明二维数组,并且使每个一维数组的长度可以不同
int[][] arr = new int[10][];
// 需要 单独初始化每一个一维数组的长度
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i+1];
}
// 遍历
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
运行结果如图:
三、交换变量的值
以下三种方法均可以交换a,b的值,中间变量最常用
public class Array_01 {
public static void main(String[] args) {
int a = 9;
int b = 10;
// 1 中间变量(开发常用)
int temp = a;
a = b;
b = temp;
// 2 加减法
a = 9;
b = 10;
a = a + b;
b = a - b;
a = a - b;
// 3 位异或
a = 9;
b = 10;
// a和b的二进制
// a=9 0 000 1001
// b=10 0 000 1010
a = a ^ b;
// a= 0 000 0011//异或后的值
b = a ^ b;
// b= 0 000 1001
a = a ^ b;
// a= 0 000 1010
System.out.println("a=" + a + " , b=" + b);
}
}