什么是数组?
数组本质上就是让我们能 “批量” 创建相同类型的变量.(我们需要少量变量的时候可以一个一个的创建,但是如果需要显示一万个变量呢?我们就需要使用数组来批量创建)
创建数组
//动态创建数组
//数据类型[] 数组名称 = new 数据类型 [];
int[] arr = new int[5];//默认全为0
//静态创建数组
// 数据类型[] 数组名称 = { 初始化数据 };
int[] arr = {1,2,3,4,5};
//创建二维数组,二维数组本质上是一维数组,不过每个元素又是一个一维数组
//数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
int[][] arr = new int[][] {{1, 2, 3}, {4, 5, 6}, {6, 7, 8, 9}};//不一定是等列数组
数组的使用
- 获取数组长度&&访问数组元素
数组长度是通过数组名.length 来获取的,注意访问数组元素的范围为[0,length-1],不在这个范围内就会数组下标越界异常(执行之后就是这个样子滴报错-- java.lang.ArrayIndexOutOfBoundsException)
int[] arr = {1,2,3,4,5};
// 获取数组长度
System.out.println(arr.length); // 执行结果: 5
// 访问数组中的元素
System.out.println(arr[1]); // 执行结果: 2
- 打印数组内容
public static void main(String[] args) {
int[] arr = {1, 2, 3};
//调用方法直接打印
System.out.println(Arrays.toString(arr));
//自己实现一个打印方法
toString(arr);
}
public static void toString(int[] arr){
String ret = "[";
for(int i = 0;i < arr.length;i++){
ret += arr[i];
if(i != arr.length-1){
ret += ",";
}
}
System.out.println(ret+"]");
}
}
-数组作为方法的参数
在函数内部修改数组内容, 函数外部也发生改变.此时数组名 arr 是一个 “引用”(本质上是一个地址) . 引用相当于一个 “别名”, 创建一个引用相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址.
修改数组内容前
修改数组内容后
public static void main(String[] args) {
int a = 1;
int b = 2;
int[] arr1 = {1,2,3};
//这里只是把形参x和y交换了,对于实参没有影响,并不会发生交换
func1(a,b);
//在函数内部修改数组内容, 函数外部也发生改变.此时数组名 arr 是一个 "引用" ,引用本质上是存了一个地址.
func2(arr1);
System.out.println("a =" + a); //a =1
System.out.println("arr1[0] =" + arr1[0]); //arr1[0] =2
}
public static void func1(int x,int y) {
int tmp = x;
x = y;
y = tmp;
}
public static void func2(int[] arr){
int tmp = arr[0];
arr[0] = arr[1];
arr[1] = tmp;
}
常见数组习题
- 数组拷贝
int[] newArr = Arrays.copyOf(arr, arr.length); //拷贝整个数组
int[] newArr = Arrays.copyOfRange(arr, 2, 4);//这是拷贝一定范围
copyOf 是将数组进行了 深拷贝, 即又创建了一个数组对象, 拷贝原有数组中的所有元素到新数组中. 因此修改原数组, 不会影响到新数组,以下是自己实现的拷贝
public static int[] mycopyOf(int[] arr){
int[] newArr = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i];
}
return newArr;
}
- 找到数组最大值
是相当于打擂台的方式,max作为擂台,遍历比较,碰到大的就替换擂主,没有更大的就继续下一个直到遍历完
public static int max(int[] arr){
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(max < arr[i]){
int tmp = max;
max = arr[i];
arr[i] = tmp;
}
}
return max;
}
- 二分法查找指定元素
针对有序数组, 先取中间位置的元素, 看要找的值比中间元素大还是小. 如果小, 就去左边找; 否则就去右边找.数组长度越长二分查找的优势会越大
public static int binarySerch(int[] arr,int toSearch){
int left = 0;
int right = arr.length-1;
while (left < right) {
int mid = (left + right) / 2;
for (int i = 0; i < arr.length; i++) {
if (toSearch < arr[mid]) {
right = mid-1;
} else if (toSearch > arr[mid]) {
left = mid+1;
} else {
return mid;
}
}
}
return -1;
}
- 数组排序(冒泡)
public static void bubbleSort(int[] arr){
for (int bound = 0; bound < arr.length; bound++) {
for(int cur = arr.length-1;cur> bound;cur--){
if(arr[cur] < arr[cur-1]){
int tmp = arr[cur];
arr[cur] = arr[cur-1];
arr[cur-1] = tmp;
}
}
}
}
- 数组逆序
设定left,right分别指向第一个元素和最后一个元素. 交换两个位置的元素.然后让前一个下标自增, 后一个下标自减, 循环继续.
public static void reserve(int[] arr){
int left = 0;
int right = arr.length-1;
while (left < right) {
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
right--;
left++;
}
}
- 数组数字排列
给定一个整型数组, 将所有的偶数放在前半部分, 将所有的奇数放在数组后半部分
public static void transform(int[] arr){
int left = 0;
int right = arr.length-1;
while(left < right){
if(arr[left] %2 == 0 ){
left++;
}
if (arr[right] %2 != 0){
right--;
}else {
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
}
}