package DataStructures; import java.util.*; public class Array_array { /* * 数组 * 定义:数组是一组同种类型的数据的集合 * Note: * 1.数组的下标索引是从0开始 * 2.数组中的元素可以是任意数据类型,但是所有的元素的类型相同,例如int,float,double,char,String等 * 3.常用一维和二维数组,其他的高维数组不经常用,但是使用方法类似 * 4.数组是引用数据类型,引用数据类型使用之前要进行声明以及初始化。数组变量不是数组本身,而是指向堆内存中的数组对象 * 5.声明一个数组将在内存空间中为其分配一个连续空间,数组的名字代表的是这连续空间的首地址,通过首地址能访问数组中所有元素 * 6.数组的使用:声明数组、初始化(分配空间以及赋值)、操作数组 * 7.int[] 就是一种数据类型,与 int 类型、String 类型相似,一样可以使用该类型来定义变量,也可以使用该类型进行类型转换等。 * 使用 int[] 类型来定义变量、进行类型转换时与使用其他普通类型没有任何区别。int[] 类型是一种引用类型,创建 int[] 类型的 * 对象也就是创建数组,需要使用创建数组的语法。 */ public static void main(String[] args) { //数组的定义和初始化 //1.声明数组,指定数组的元素类型 /* * Note: * 1.声明数组变量的时候有两种方式,但是java中更推荐第一种([]括号在元素数据类型之后) * 2.不要忘记括号 * 3.此时只是声明数组变量,不需要给定数组的大小 */ //以int类型数组为例 int[] ar_i_1; int ar_i_2[]; //2.分配空间 /* * Note: * 1.声明数组后,要给数组变量分配存储空间,使用new关键字进行空间分配 * 2.[]中为数组长度,当确定数组的大小后,不能更改,且数组长度时必须的 * 3.当确定数组的长度后,系统根据数据中的元素的数据类型对数组分配初始值 * (1)byte\short\int\long --- 0 * (2)float\double --- 0.0 * (3)char --- \u0000 * (4)boolean --- false * (5)引用类型(类、接口、数组) --- null */ ar_i_1 = new int[2]; ar_i_2 = new int[5]; //3.赋值 /* * Note: * 1.数组是一个有序的集合,除了对数组中单个元素单独的赋值,可以通过循环对数组元素进行赋值(操作) */ ar_i_1[0] = 11; ar_i_1[1] = 12; for(int i = 0; i < 5; i++) { ar_i_2[i] = i; } //数组其他初始化方式 /* * Note: * 1.数组初始化可以分为两种方式:静态初始化和动态初始化 * (1)静态初始化:初始化时由程序员显示的指定数组元素的初始值,由系统决定数组长度 * (2)动态初始化:初始化有程序员指定数组长度,由系统为数组元素分配初始值 */ //可以将1和2同时进行,之后再对数组进行赋值 int[] ar_i_3 = new int[5]; //创建数组时同时对数组中元素赋值(使用new) /* * Note: * 1.这种初始化方式,不需要指定数组长度,如果指定数组长度并进行赋值,会报错 */ int[] ar_i_4 = new int[] {1,2,3}; //创建数组时同时对数组中元素赋值(不使用new) /* * Note: * 1.使用这种方式时,声明和初始化要同时进行,不能分开(不能省略数组变量的类型) * int[] ar_i_5; * ar_i_5 ={1,2,3}; */ int[] ar_i_5 = {1,2,3}; //二维数组 /* * Note: * 1.二维数组的定义和初始化差不多,就不想详细解释 * 2.二维数组是存储一维数组的数组,即每个元素是一个数组 * 3.二维数组可以是不规则的,即每个元素为一个一维数组,每个一维数组的长度可以不一样 */ char[][] ar_c1; char ar_c2[][]; char[][] ar_c3 = new char[][] {{'1','2'},{'3','4'}};//定义时初始化 char[][] ar_c4 = new char[][] {{'1','2'},{'1','2','3'}};//定义时初始化 char[][] ar_c5 = new char[2][3];//定义并给定空间,随后进行初始化 char[][] ar_c6 = new char[2][];//数组的二维长度为空,可以变化 //数组元素的操作 /* * Note: * 1.java.util包中的Array类包含了操作数组的各种方法,可以直接调用相关的方法,想要了解更多和详细的,可以查看java的API文档 * 2.关于对数组的操作,可以根据实际情况或者应用进行变换 */ //数组有一个length属性,可以获得数组的长度 int len_ar = ar_i_1.length; //数组的遍历或获取数组元素(数组元素查询) //获取全部元素(遍历整个数组) /* * Note: * 1.一维数组需要一重循环;二维数组需要二重循环.... */ int[] arr1 = new int[] {1,2,3,4,5,6,1,2,3}; int[][] arr2 = new int[][] {{11,12,13},{21,22}}; PrintAllElement1(arr1); PrintAllElement2(arr2); //获取数组的单个元素 //已知元素的位置,获取该位置元素的值 int arr1_value = SelectElementValue1(arr1, 2); System.out.println(arr1_value); int arr2_value = SelectElementValue2(arr2, 1, 1); System.out.println(arr2_value); //已知元素的值,获取元素所在的位置 /* * Note: * 1.一般通过值查找数组中该元素的位置时,如果数组中存在重复的元素的值,就会有多个位置,有的方法是返回查找的到的第一个元素 * 的位置,可以根据需求来更改算法。 * 2.返回的是数组的索引,如果需要的数组重元素的位置,需要进行变换 * 3.当数组较大时,遍历整个数组耗费时间较长,故可以其他方法减少查找的时间,如二分查找等 */ int arr1_pos = SelectElementPosition1(arr1, 2); System.out.println(arr1_pos); int[] arr2_pos = new int[2]; arr2_pos = SelectElementPosition2(arr2, 12); System.out.println(arr2_pos[0] + " " + arr2_pos[1]); //数组扩容(数组元素增加) /* * * Note: * 1.创建数组后,数组的大小不能更改,但申请一个较大的空间,会造成空间的浪费 * 2.扩容方法:思想就是创建一个新的长度的数组,并将原来的数组复制过去 * (1)通过创建新的数组同时增加数组的长度 * (2)Arrays.copyOf(原数组名,新的数组的长度) * (3)System.arraycopy(原数组名,起始下标,新数组名,起始下标,复制长度) */ int[] arr3 = new int[10]; arr3 = ArrayCapacity(arr1, 10); for(int i = 0; i < arr3.length; i++) System.out.print(arr3[i] + " "); System.out.println(); int[] arr4 = Arrays.copyOf(arr1, 10); for(int i = 0; i < arr4.length; i++) System.out.print(arr4[i] + " "); System.out.println(); int[] arr5 = new int[20]; System.arraycopy(arr1, 0, arr5, 0, arr1.length); for(int i = 0; i < arr5.length; i++) System.out.print(arr5[i] + " "); System.out.println(); //数组元素删除 /* * Note: * 1.数组元素被删除后,数组的长度发生变化,可以根据数组扩容的思想进行相应的操作(需要新的存储空间),也可以进行覆盖(不许新的存储空间) * 2.第一种方法简单容易理解,删除元素后,数组还保持原先的顺序,但是需要开辟新的存储空间,而且需要知道新的开辟的空间的大小 * 3.第二种方法是通过删除这个元素后,后边的元素去覆盖这个位置的元素 * (1)有序:被删除位置元素之后的元素依次向前移动进行覆盖 * (2)无序:可以选择从数组最后边选择元素进行覆盖 * 4.可以根据索引删除数组元素,也可以根据元素值删除 * (1)根据索引删除,可以明确知道删除元素的个数 * (2)根据元素的值来删除数组元素(删除的元素有多个重复的,使用创建新数组的方法不知道新数组的大小,使用覆盖的方法会更方便) */ int[] arr6 = new int[arr1.length - 1]; arr6 = RemoveElement1(arr1, 1); PrintAllElement1(arr6); int arr_po = RemoveElement2(arr1, 1); for(int i = 0; i < arr1.length - arr_po; i++) System.out.print(arr1[i] + " "); System.out.println(); //数组元素修改 /* * Note: * 大多数情况下是根据索引进行数组元素的值的修改,其他情况以后想到了在更新 */ arr1[1] = 9; for(int i = 0; i < arr1.length; i++) System.out.print(arr1[i] + " "); System.out.println(); //数组复制 /* * Note: * 1.使用循环,一个一个元素的赋值 * 2.System.arraycopy() * 3.Arrays.copyOf() * 4.Object.clone() * 效率:System.arraycopy() > Object.clone() > Arrays.copyOf() > 循环 * 1、2、3之前都用到过,就省略了,主要说说4 */ int[] arr7 = new int[9]; arr7 = arr1.clone(); for(int i = 0; i < arr7.length; i++) System.out.print(arr7[i] + " "); System.out.println(); /* * Note: * 还有一些会用直接赋值的方法,这是对数组的引用,指向同一个数组(对象),当对数组进行修改时,原数组也会发生变化 */ int[] arr8; arr8 = arr1; for(int i = 0; i < arr8.length; i++) System.out.print(arr8[i] + " "); System.out.println(); //Object.hashCode() 默认返回内存地址 System.out.println(arr1.hashCode()); System.out.println(arr8.hashCode()); //数组连接 /* * Note: * 根据需求的不同可以进行数组合并,简单的数组合并、去重合并、排序合并、去重并排序合并等等; * 这里就简单的进行合并,后面可以根据需求进行合并; * 合并的方法也有很多种,这里就根据前面提到的进行合并 */ int[] arr9 = new int[] {9,8,7,6}; int[] arr10 = new int[arr1.length + arr9.length]; //将arr1数组复制到arr10中 System.arraycopy(arr1, 0, arr10, 0, arr1.length); //将arr9数组复制到arr10中,接着arr1 System.arraycopy(arr9, 0, arr10, arr1.length, arr9.length); for(int i = 0; i < arr10.length; i++) System.out.print(arr10[i] + " "); System.out.println(); //数组反转 /* * Note: * 1.可以将数组倒序复制到新的数组中 * 2.可以将数组的首尾相应元素互换,直至数组倒序 */ int[] arr11 = new int[9]; arr11 = ReverseArray1(arr1); for(int i = 0; i < arr11.length; i++) System.out.print(arr11[i] + " "); System.out.println(); int[] arr12 = new int[9]; arr12 = ReverseArray2(arr1); for(int i = 0; i < arr12.length; i++) System.out.print(arr12[i] + " "); System.out.println(); //数组比较 /* * Note: * 数组比较(是否相等,数组大小等),可以通过循环对相应位置的元素逐一比较,但是不能直接arr1==arr9进行比较 * java中Arrays类提供了比较的方法,可以直接调用 */ System.out.println(Arrays.equals(arr1, arr9)); //数组排序 /* * Note: * 数组排序,有很多的方法,之后会专门在复习相关的排序算法,这里就不多讲了 * java中Arrays类提供了排序的方法,可以直接调用 */ Arrays.sort(arr1); for(int i = 0; i < arr1.length; i++) System.out.print(arr1[i] + " "); System.out.println(); //数组中经常出现的异常 /* * Note: * 1.NullPointerException 空指针异常 * 原因:引用类型变量没有指向任何对象,而访问了对象的属性或者是调用了对象的方法 * 2.ArrayIndexOutOfBoundsException 索引值越界 * 原因:访问了不存在的索引值。 */ } //获得一维数组全部的元素 public static void PrintAllElement1(int[] arr) { for(int i = 0; i < arr.length; i++) System.out.print(arr[i] + " "); System.out.println(); } //获得二维数组全部的元素 public static void PrintAllElement2(int[][] arr) { 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(); } } //查找数组中的元素---一维数组(已知位置,查找值) /* * Note: * 我们的习惯是从1开始,但是数组中是从0开始,要进行换算 */ public static int SelectElementValue1(int[] arr, int pos) { int value = arr[pos - 1]; return value; } //查找数组中的元素---二维数组(已知位置,查找值) public static int SelectElementValue2(int[][] arr, int xpos, int ypos) { int value = arr[xpos - 1][ypos - 1]; return value; } //查找数组中的元素---一维数组(已知值,查找位置(返回第一个元素的位置)) public static int SelectElementPosition1(int[] arr, int value) { int pos = 0; for(int i = 0; i < arr.length; i++) { if(arr[i] == value) { pos = i; break; } } //返回的是元素在数组中的索引 return pos; } //查找数组中的元素---二维数组(已知位置,查找值) public static int[] SelectElementPosition2(int[][] arr, int value) { int[] pos = new int[2]; for(int i = 0; i < arr.length; i++) { for(int j = 0; j < arr[i].length; j++) { if(arr[i][j] == value) { pos[0] = i; pos[1] = j; break; } } } return pos; } //数组扩容--第二个参数是扩容数组的长度 public static int[] ArrayCapacity(int[] arr, int len) { int[] arr1 = new int[len]; for(int i = 0; i < arr.length; i++) { arr1[i] = arr[i]; } return arr1; } //删除元素--根据索引删除 public static int[] RemoveElement1(int[] arr, int pos) { //根据索引删除元素,传入几个索引就减去几个空间(Note:可以加入判断索引值是否越界) int[] arrNew = new int[arr.length - 1]; int j = 0; for(int i = 0; i < arr.length; i++) { if(i != pos) { arrNew[j] = arr[i]; j++; } } return arrNew; } //删除元素--根据元素删除 public static int RemoveElement2(int[] arr, int ele) { int pos = 0; for(int i = 0; i < arr.length; i++) { if(arr[i] == ele) { pos++; for(int j = i; j < arr.length - pos; j++) { arr[j] = arr[j + 1]; } } } return pos; } //数组逆序(反转)--法一 public static int[] ReverseArray1(int[] arr) { int[] arrNew = new int[arr.length]; int j = 0; for(int i = arr.length - 1; i >= 0; i--) { arrNew[j] = arr[i]; j++; } return arrNew; } //数组逆序(反转)--法二 public static int[] ReverseArray2(int[] arr) { for(int i = 0; i < arr.length; i++) { int temp; temp = arr[i]; arr[i] = arr[arr.length - 1 - i]; arr[arr.length - 1 - i] = temp; } return arr; } }
该类包含用于操作数组的各种方法(如排序和搜索)。 该类还包含一个静态工厂,可以将数组视为列表。如果指定的数组引用为空,则该类中的方法都抛出一个NullPointerException
,除非另有说明。如果想要看更详细的内容可以查看java的API文档。
static String | toString(type[] a) 返回指定数组的内容的字符串表示形式。 |
static void | sort(type[] a, int fromIndex, int toIndex) 按照数字顺序排列指定的数组(可以指定范围,默认升序) |
static void | parallelSort(type[] a,int fromIndex, int toIndex) 按照数字顺序排列指定的数组(可以指定范围) |
static int | hashCode(type[] a) 根据指定数组的内容返回哈希码 |
static void | fill(type[] a, int fromIndex, int toIndex, type val) 将指定类型的元素分配给指定数组的每个元素(可以指定范围) |
static boolean | equals(type[] a, type[] a2) 如果两个指定的数组彼此 相等 ,则返回 true 。 |
static int[] | copyOf(int[] original, int newLength) 复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。 |
static int[] | copyOfRange(int[] original, int from, int to) 将指定数组的指定范围复制到新数组中。 |
static type | binarySearch(type[] a, type key) 使用二叉搜索算法搜索指定数组的指定值。 |
static type | binarySearch(type[] a, int fromIndex, int toIndex, type key) 使用二叉搜索算法搜索指定值的指定数组的范围。 |