🎨1.Java 数组的基本用法
🎳1.1 数组的定义方式
🍁方式 1:
 数据类型[] 变量名 = 元素1,元素2,元素3,...,元素n;
   
 int[] arr = 1,2,3,4,5,6,7,8,9,0;
   
🍁方式 2:
 数据类型[] 变量名 = new int[]元素1,元素2,元素3,...,元素n;
   
 int[] arr = new int[]1,2,3,4,5,6,7,8,9,0;
   
❗️new后面那个中括号里面不能指定元素个数,必须是空的!
🍁方式 3:
 数据类型[] 变量名 = new int[元素个数]; (数组全部元素会初始化为0)
   🎳1.2 数组的创建与使用
🍁数组的创建:
 int[] data1 = {1,2,3,4,5,6,7,8,9,0};int[] data2 = new int[]{1,2,3,4,5,6,7,8,9,0};int[] data3 = new int[10];
   复制代码
 
🍁数组的使用:
 import java.util.Arrays;
public class TestBlog {    public static void main(String[] args) {        //创建数组        int[] arr = new int[]{1,2,3,4,5,6,7,8,9,0};        //访问数组长度        System.out.println(arr.length);        //访问数组元素        System.out.println(arr[0]);        System.out.println(arr[1]);        System.out.println(arr[2]);        //遍历数组 1.for循环   2.foreach循环   3.toString函数
        //方式1:for循环        for (int i = 0; i < arr.length; i++) {            System.out.print(arr[i] + "  ");        }        System.out.println();        //方式2:foreach循环        for (int a: arr) {            System.out.print(a + "  ");        }        System.out.println();        //方式3:toString函数        System.out.println(Arrays.toString(arr));    }}
   复制代码
 
对于数组遍历方式 2:
 for (接受变量: 数组) {  //语句块;  //此方法不能获取下标}
   复制代码
 
对于遍历方式 3:toString是 JavaArrays类中的一个方法,能够将数组转换成字符串,有,隔开元素,中括号[]包裹数组所有元素!
🎨2.Java 类型之引用
🎳2.1 引用类型
在 Java 当中数组其实是一个对象,我们知道在数组定义时有两种方式都用到了关键字new,这个关键字就是实现类的实例化,实例出一个对象,使用一个能接收“实例化对象的值”的类型就是引用类型。这个“实例化对象的值”其实是一个地址,该地址指向该数组(对象),比如下面定义的x变量定义一个数组,这个x就是引用变量。这个与 C 语言中的指针有一点相似,但是它并不是指针,引用变量是一个值,在这里,该值是这个数组的地址。我们知道我们所定义的x变量是局部变量所以它在栈上生成,而这个数组(对象)是在堆上开辟内存的。null表示空引用,与 C 语言中的NULL很相似,表示一个无效的内存位置,既然这个内存是无效的,那肯定就不能对这个内存指向的空间进行读写。注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联.
 数据类型[] 变量名 = new int[元素个数]; (数组全部元素会初始化为0)int[] x = new int[3];x[0] = 10;x[1] = 20;x[2] = 30;
   复制代码
 
所谓的 "引用" 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大)下面用一个数组传参的例子来进一步理解引用。
🎳2.2 数组传参
 public class TestBolg {    public static void arrFunc(int[] arr) {        if (arr == null) {            return;        }        for (int i = 0; i < arr.length; i++) {            arr[i] = 10 * (i+1);        }    }    public static void main(String[] args) {        int[] x = new int[3];        arrFunc(x);        System.out.println(Arrays.toString(x));    }}
   复制代码
 
对于数组的传参就是将一引用变量的值传递给方法的形参,由于引用变量存的是对象的地址,所以方法会根据传入的参数对数组(实例化的对象)进行修改或读写操作,从而使数组内元素的值发生改变,这就是引用传递。
🎳2.3 认识 JVM 区域划分
🎨3.Java 数组应用
🎳3.1 利用数组求平均值与交换两个数
 public class AvgSwap {    public static void swap(int[] data) {        int tmp = data[0];        data[0] = data[1];        data[1] = tmp;    }    public static double avg(int[] data) {        int sum = 0;        for (int i = 0; i < data.length; i++) {            sum += data[i];        }        return 1.0 * sum / data.length;    }
    public static void main(String[] args) {        int[] swap = {22, 33};        int[] avg = {1,2,3,4,5,6,7,8,9,0};        System.out.println("数据交换前:a = " + swap[0] + ", b = " + swap[1]);        swap(swap);        System.out.println("数据交换后:a = " + swap[0] + ", b = " + swap[1]);        System.out.println("数组平均值为:" + avg(avg));    }}
   复制代码
 
🎳3.2 拷贝数组
 import java.util.Arrays;
public class Copy {    public static int[] copy(int[] arr) {        if (arr == null) {            return null;        }        int[] copy = new int[arr.length];//新建一个数组        for (int i = 0; i < arr.length; i++) {            copy[i] = arr[i];//遍历拷贝        }        return copy;    }    public static void main(String[] args) {        int[] arr1 = {1,2,3,4,5,6,7,8,9};        System.out.println("数组1:");        System.out.println(Arrays.toString(arr1));        int[] arr2 = copy(arr1);        System.out.println("数组2:");        System.out.println(Arrays.toString(arr2));    }}
   复制代码
 
当然 Java 中的Arrays
类有内置的拷贝方法:<font color = orange>
 static 数据类型[] copyOf(数据类型[] original, int newLength)
   
</font>复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
<font color = orange>
 static 数据类型[] copyOfRange(数据类型[] original, int from, int to)
   
</font>将指定数组的指定范围[from, to)
复制到新数组中。<font color = orange>
 static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
   
</font>Object src表示源数组,srcPos表示从源数组开始拷贝的下标位置,Object dest表示目标数组,destPos表示表示从目标数组开始拷贝的下标位置,length表示拷贝数组元素个数。如果细心去查看该方法源代码,会发现该方法被native修饰,这个表示这个方法是使用C/C++
实现的。将指定源数组中的数组从指定位置复制到目标数组的指定位置。<font color = orange>
</font>
最后一种就是利用数组名.clone创建并返回此对象的副本。 “复制”的精确含义可能取决于对象的类。因为数组实例化后就是一个对象,该方法会返回值为对应类型的数组,所以使用该方法进行拷贝。
 import java.util.Arrays;
public class Copy {
    public static void main(String[] args) {        int[] arr1 = {1,2,3,4,5,6,7,8,9};        System.out.println("arr1:" + Arrays.toString(arr1));        int[] arr2 = Arrays.copyOf(arr1, arr1.length);        System.out.println("arr2:" + Arrays.toString(arr2));        int[] arr3 = Arrays.copyOf(arr1, arr1.length * 2);        System.out.println("arr3:" + Arrays.toString(arr3));        int[] arr4 = Arrays.copyOfRange(arr1, 1, 5);        System.out.println("arr4:" + Arrays.toString(arr4));        int[] arr5 = new int[arr1.length];        System.arraycopy(arr1, 0, arr5, 0, arr1.length);        System.out.println("arr5:" + Arrays.toString(arr5));        int[] arr6 = arr1.clone();        System.out.println("arr6:" + Arrays.toString(arr6));    }}
   复制代码
 
另外,一般来说数组的拷贝是浅拷贝,因为 Java 中万物皆对象,对对象的拷贝就是浅拷贝,而数组也是一种对象,除非人为因素使实现深拷贝,如果数组中的为简单的数据类型一般都是深拷贝,如果数组中为引用类型一般都是浅拷贝。
🎳3.3 数组转换字符串
再上述代码展示中我相信大家已经看到了Arrays.toString方法的使用,它能将一个数组转换成带中括号字符串!现在我们来模拟一下这个方法:
 public class StringArray {    public static String myToString(int[] arr) {        if (arr == null) {            return "[]";//空引用返回[]        }        String str = "[";//初始化字符串为[        for (int i = 0; i < arr.length - 1; i++) {            str += arr[i] + ",";//注意最后一个数组元素后无逗号        }        str += arr[arr.length - 1] + "]";//查漏补缺,补上最后一个元素和]        return str;    }    public static void main(String[] args) {    int[] arr = {1,2,3,4,5,6,7,8,9};        System.out.println(myToString(arr));    }}
   复制代码
 
🎳3.4 数组查找
⛳️3.4.1 顺序查找
顺序查找是最简单的查找方法,直接遍历一遍数组就可以了。
 public class Search {    public static void main(String[] args) {        //顺序查找元素,找到其下标,未找到则输出未找到        int[] arr = {1,2,3,4,5,6,7,8,9};        int k = 7;        int flag = 0;        for (int i = 0; i < arr.length; i++) {            if (arr[i] == k) {                System.out.println("找到了!下标为:" + i);                flag = 1;                break;            }        }        if (flag == 0) {            System.out.println("未找到!");        }    }}
   复制代码
 
⛳️3.4.2 二分查找
然后就是我们已经非常熟悉的二分查找:
 public class BinSearch {    public static int binSearch(int[] arr, int k) {        if (arr == null) {            return -1;        }        int left = 0;        int right = arr.length - 1;        int mid = left + (right - left) / 2;        while (left <= right) {            mid = left + (right - left) / 2;            if (k > arr[mid]) {                left = mid + 1;            }            else if (k < arr[mid]) {                right = mid - 1;            }            else {                return mid;            }        }        return -1;    }    public static void main(String[] args) {        int[] arr = {1,2,3,4,5,6,7,8,9};        int k = 7;        System.out.println(binSearch(arr, k));    }}
   复制代码
 
🎳3.5 数组的排列
⛳️3.5.1 判断数组是否有序
使用两个计数棋进行计数(从 1 开始计数),遍历数组分别对数组前一项不小于后一项,数组后一项不小于前一项独立计数,如果计数结果有刚好等于数组长度的结果则数组有序。
 public class ArraryOrder {    public static boolean arrOrder(int[] arr) {        if (arr == null) {            return false;        }        int cnt1 = 1;        int cnt2 = 1;        for (int i = 0; i < arr.length - 1; i++) {            if (arr[i] <= arr[i+1]) {                cnt1++;            }            if (arr[i] >= arr[i+1]) {                cnt2++;            }        }        if (cnt1 == arr.length || cnt2 == arr.length) {            return true;        }        else {            return false;        }    }    public static void main(String[] args) {        int[] arr1 = {1,2,3,4,5,6,7,8,9};        int[] arr2 = {9,8,7,6,5,4,3,2,1};        int[] arr3 = {2,1,4,7,5,9,8,3,6};        System.out.println(arrOrder(arr1));        System.out.println(arrOrder(arr2));        System.out.println(arrOrder(arr3));    }}
   复制代码
 
⛳️3.5.2 数组逆序
双指针,依次将左边元素与右边元素互换。
 import java.util.Arrays;
public class ReverseArr {    public static void rever(int[] arr) {        if (arr == null) {            return;        }        int l = 0;        int r = arr.length - 1;        while (l < r) {            int tmp = arr[l];            arr[l] = arr[r];            arr[r] = tmp;            l++;            r--;        }    }
    public static void main(String[] args) {        int[] arr = {1,2,3,4,5,6,7,8,9};        System.out.println("逆序前:");        System.out.println(Arrays.toString(arr));        System.out.println("逆序后:");        rever(arr);        System.out.println(Arrays.toString(arr));    }}
   复制代码
 
⛳️3.5.3 冒泡排序(升序)
从数组首位元素开始将数组的相邻两个元素进行比较,如果前面的元素比后面大,则进行交换否则不交换,每进行一趟排序就能将一个最大的数放在最后,如果需要把所有元素都排好序,需要进行数组元素个数减一趟排序。因为每一趟排序都会排出一个最大的数放在后面,也就是说每排序一趟就有一个数排序完成,所以每完成一趟排序,排序比较次数就减一,假设数组元素个数为size,则一共要进行size-1趟排序,第 1 趟排序比较次数为size-1,随着趟数比较次数逐次递减,如果此时为第i趟排序,则需要比较的次数为size - 1 - i。比如 10 个元素进行冒泡排序,一共要进行 9 趟排序,第一趟需排序比较 9 次,第二趟 8 次,第三趟 7 次,以此类推。
 import java.util.Arrays;
public class BubbleSort {    public static void bubbleSort(int[] arr) {        if (arr == null) {            return;        }        for (int i = 0; i < arr.length - 1; i++) {            int flag = 0;            for (int j = 0; j < arr.length - 1 - i; j++) {                if (arr[j] > arr[j+1]) {                    int tmp = arr[j];                    arr[j] = arr[j+1];                    arr[j+1] = tmp;                    flag  = 1;                }            }            if (flag == 0) {                break;            }        }    }    public static void main(String[] args) {        int[] arr = {2,1,8,5,9,4,6,7,3};        System.out.println("排序前:");        System.out.println(Arrays.toString(arr));        bubbleSort(arr);        System.out.println("排序后:");        System.out.println(Arrays.toString(arr));    }}
   复制代码
 
🎨4.二维数组
二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组.
前面我们知道了,我们是使用引用来指向一个数组的,那么二维数组其实一个类型为引用的数组,数组中的每个元素都是一个引用变量,引用变量中指向另一个一维数组。
二维数组定义:
 数据类型[][] 数组名称 = new 数据类型 [行数][列数] 初始化数据
   
 数组名称.length;//表示行数数组名称[行数].length;//表示某一行的列数
   复制代码
 
 public class TestBolg {    public static void main(String[] args) {        int[][] arr = new int[3][3];        for (int i = 0; i < arr.length; i++) {            for (int j = 0; j < arr[i].length; j++) {                arr[i][j] = 8 + i +j;            }        }        for (int i = 0; i < arr.length; i++) {            System.out.println(Arrays.toString(arr[i]));        }    }}
   复制代码
 
同理, 还存在 "三维数组", "四维数组" 等更复杂的数组。
评论