一、一维数组
(一)初始化
1、静态初始化:给出初始值,系统决定长度
<span style="font-family:Arial;font-size:18px;">int[] sArr = {1,2,3}; String[] sArrStr = {"a","b","c"};</span>
2、动态初始化:只指定长度,系统给出初始值
<span style="font-family:Arial;font-size:18px;">int[] dArr = new int[3];//分配空间 dArr[0] = 1; dArr[1] = 2; dArr[2] = 3; String[] dArrStr = new String[4];//分配空间 </span>
3、赋值操作:引用值的指向
<span style="font-family:Arial;font-size:18px;"> public void test2(){ int[] arr1= new int[2]; arr1[0]= 0; arr1[1]= 1; System.out.println(arr1[0]);// 0 System.out.println(arr1[1]);// 1 System.out.println("*****************************"); int[] arr2 = arr1;//相当于把数组1的地址同样给了数组2 arr2[0] = 100; arr2[1] = 200; System.out.println(arr1[0]);//100 System.out.println(arr1[1]);//200 System.out.println(arr2[0]);//100 System.out.println(arr2[1]);//200 } </span>
(二)内存分配
1、一个数组
2、多个数组:注意引用值的拷贝
(三)常见操作
1、遍历:几乎所有数组的操作,都是可以用循环解决的。
<span style="font-family:Arial;font-size:18px;"> /** * 循环操作 */ public void test3(){ int[] arr = {298,2,14,345,256,89,100,7}; //循环操作1 int len = arr.length; for (int i = 0; i < len; i++) { System.out.println(arr[i]); } System.out.println("-----------------------"); //循环操作2 for (int i : arr) { System.out.println(i); } } </span>
2、获取最值:预定索引【0】是最大,循环,比较。
<span style="font-family:Arial;font-size:18px;"> /** * 获取最值 */ public void test4(){ int[] arr = {298,2,14,345,256,89,100,7}; int max = arr[0]; for (int i = 1; i < arr.length; i++) { max = max > arr[i] ? max : arr[i]; } System.out.println("数组中最大的值 : "+max); } </span>
3、数组元素逆序:
<span style="font-family:Arial;font-size:18px;"> /** * 数组元素逆序 * [298, 2, 14, 345, 256, 89, 100, 7] * [7, 100, 89, 256, 345, 14, 2, 298] */ public void test5(){ int[] arr = {298,2,14,345,256,89,100,7}; // 方法一:0和(length-1),1和((length-1-1)一次类推 for (int i = 0; i < arr.length/2; i++) { int temp = arr[i]; arr[i] = arr[arr.length-1-i]; arr[arr.length-1-i] = temp; } //方法二 for (int start = 0,end=arr.length-1; start <= end; start++,end--) { int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; } } </span>
4、数组查表法
<span style="font-family:Arial;font-size:18px;"> /** * 数组查表法 */ public void test6(){ String[] strArr = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"}; Scanner sc = new Scanner(System.in);//得到键盘输入 int index = sc.nextInt(); System.out.println("你要找的日期为 : " + strArr[index]); } </span>
5、数组元素查找:基本查找,Arrays提供了二分查找。
<span style="font-family:Arial;font-size:18px;"> /** * 数组元素查找 */ public void test7(){ int[] indexArr = {1,2,3,4,5,3}; int task = 3; //基本查找 for (int i = 0; i < indexArr.length; i++) { if(task == indexArr[i]){ System.out.println("下标为: " + i); break;//加break的话,只取到第一次出现的索引 } } System.out.println(Arrays.binarySearch(indexArr, 3));//二分查找 } </span>
6、int类型数据转换为数组*
<span style="font-family:Arial;font-size:18px;"> /** * int数据转成数组 */ public static void jiamiDemo(){ //int数据转成数组 int number =1234567;//定义数据 int len = 8; int[] arr = new int[len];//定义数组 //把数据中每一位上的数据获取后存储到数组中 // int index = 0; // arr[index] = number%10; // index++; // arr[index] = number/10%10; // . // . //利用取余获取每一位上的值 int index = 0; while(number > 0) { arr[index] = number%10; index++; number/=10;//一次获取位数的值 } for (int i = 0; i < index; i++) { System.out.print(arr[i]); } } </span>
7、数组的拷贝
1)简单拷贝:注意浅拷贝与深拷贝的区别
<span style="font-family:Arial;font-size:18px;"> /** * 简单拷贝 */ public void test8() { String[] arr = {"a","b","a","b","a4","b5"}; String[] copyArr; // 浅拷贝:地址值(引用值). // 即arr与copyArr指向【堆】同一个数组 copyArr = arr; arr[3] = "9999999999";//指向同一个地址,修改arr,copyArr也会改变 System.out.println(Arrays.asList(copyArr)); // 深拷贝,指向不同的引用: // 方法一:循环 copyArr = new String[arr.length]; for (int i = 0; i < arr.length; i++) { copyArr[i] = arr[i]; } arr[3] = "改值";//修改arr不影响 System.out.println(Arrays.asList(copyArr)); // 方法二:clone。 copyArr = arr.clone(); arr[2] = "22222";//修改不影响 System.out.println(Arrays.asList(copyArr)); // 方法三:arraycopy()。 // copyArr = new String[arr.length];//不new 一个,则是浅拷贝;new一个则为深拷贝。 System.arraycopy(arr, 0, copyArr, 0, arr.length); arr[2] = "22222888"; System.out.println(Arrays.asList(copyArr)); // 方法四:Arrarys类的copyOf()方法与copyOfRange()方法可实现对数组的复制 copyArr = Arrays.copyOf(arr, arr.length); copyArr = Arrays.copyOfRange(arr, 0, arr.length); arr[4] = "12345"; System.out.println(Arrays.asList(copyArr)); } </span>
2)复杂拷贝:这道题以前在“科沃斯(苏州)”被面试过。
<span style="font-family:Arial;font-size:18px;"> /** * 数组的拷贝 * 1,2 拷贝到 3 */ public void test9(){ String[] arr = {"a","b","a","b"}; String[] arr2 = {"1","2","3"}; int len = arr.length; int len2 = arr2.length; String[] copyArr = new String[len+len2]; // 方法一:使用System.arraycopy()方法 System.arraycopy(arr, 0, copyArr, 0, len); System.arraycopy(arr2, 0, copyArr, len, len2); // 方法二:循环 for (int i = 0; i < len; i++) { copyArr[i] = arr[i]; } for (int i = 0; i < len2; i++) { copyArr[len+i] = arr2[i]; } System.out.println(Arrays.asList(copyArr)); // 方法三:ArrayList List<String> list = new ArrayList<String>(); for (int i = 0; i < len; i++) { list.add(arr[i]); } for (int i = 0; i < len2; i++) { list.add(arr2[i]); } Object [] aa = list.toArray();//利用List的toArray()方法 System.out.println(Arrays.asList(aa)); } </span>
二、二维数组
(一)初始化
1、动态初始化
1)格式1
<span style="font-family:Arial;font-size:18px;">int[][] arr = new int[3][2];</span>
2)格式2
<span style="font-family:Arial;font-size:18px;">int[][] arr2 = new int[2][]; arr2[0] = new int[2]; arr2[1] = new int[3];</span>
2、静态初始化
<span style="font-family:Arial;font-size:18px;">int[][]arr3 = {{1,2},{3,4,5}};</span>
(二)内存图解
1、动态初始化1
- 3个一维数组,每个一维数组有2个元素。
- 分配空间,存在地址值。二维数组中一维数组,默认为空。等每个一维数组构造完毕,才会分配空间,附上引用值。
- Java中没有二维数组的概念,其实二维数组就是一维数组组成的,存放的是引用值。
- 即会有两类引用值,二维的引用值赋予【栈】内存,一维的引用赋予二维。
2、动态初始化2
3、静态初始化:自动会new一维数组。
(三)简单操作
1、遍历:二次循环
<span style="font-family:Arial;font-size:18px;"> /** * 遍历 */ private void test2() { int[][] arr = {{1,2},{3,4,5},{6,7,8,9}}; 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(); } System.out.println("*****************************************************8"); } </span>
2、求和
<span style="font-family:Arial;font-size:18px;"> /** * 求和 */ private void test3() { int[][] arr = {{1,2},{3,4,5},{6,7,8,9}}; int sum = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { sum += arr[i][j]; } } System.out.println("求和: " + sum); } </span>
3、杨辉三角
<span style="font-family:Arial;font-size:18px;"> /** * 杨辉三角 * 任何一行的第一列和最后一列都是1 * 从第三行开始,每一个数据时它上一行的前一列和它上一行的本列之和,最后一列除外。 * 1 * 1 1 * 1 2 1 * 1 3 3 1 * 1 4 6 4 1 * 1 5 10 10 5 1 */ public void test4(){ //创建键盘录入对象 Scanner scanner = new Scanner(System.in); // 这个n的数据来自键盘录入 int n = scanner.nextInt(); //定义一个二维数组 int[][] arr = new int[n][n]; // 给这个二维数组任何一行的第一列和最后一列赋值1 for (int i = 0; i < arr.length; i++) { arr[i][0] = 1;//任何一行第1列 arr[i][i] = 1;//任何一行最后1列 } // 从第三行开始,每一个数据时它上一行的前一列和它上一行的本列之和,最后一列除外。 // 第3行,第2列开始,所以i=2,j=1开始 for (int i = 2; i < arr.length; i++) { // 不能取最后一列,所以减去1,j <= i-1 for (int j = 1; j <= i-1; j++) { arr[i][j] = arr[i-1][j-1] + arr[i-1][j]; } } //遍历二维数组 for (int i = 0; i < arr.length; i++) { for (int j = 0; j <= i; j++) { System.out.print(arr[i][j]+" "); } System.out.println(); } } </span>
三、数组高级
(一)排序算法(介绍被面试过的2种)
1、冒泡排序(被面到过好几次,如上海安硕(信贷系统)、科沃斯)
1)原理:相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。同理,继续,即可得到一个排好序的数组。
- 两两比较,大的往后放
- 总共需要比较数组长度的 -1 次。(外层循环)
- 每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环)
2)分析图:
3)代码实现
<span style="font-family:Arial;font-size:18px;"> /** * 冒泡排序: * 数组排序之冒泡排序: * 相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处 * * 外循环:一共是 arr.length-1 次循环循环 * 内循环:每次循环都会少一次 * * 两两比较,大的往后放 * 总共需要比较数组长度的 -1 次。(外层循环) * 每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环) */ private void test1() { // 定义一个数组 int[] arr = { 24, 69, 80, 57, 13 }; System.out.println("排序前:"); printArray(arr); // 第一次比较 // arr.length - 1是为了防止数据越界 // arr.length - 1 - 0是为了减少比较的次数 /* for (int x = 0; x < arr.length - 1 - 0; x++) { if (arr[x] > arr[x + 1]) { int temp = arr[x]; arr[x] = arr[x + 1]; arr[x + 1] = temp; } } System.out.println("第一次比较后:"); printArray(arr);*/ // 第二次比较 // arr.length - 1是为了防止数据越界 // arr.length - 1 - 1是为了减少比较的次数 /* for (int x = 0; x < arr.length - 1 - 1; x++) { if (arr[x] > arr[x + 1]) { int temp = arr[x]; arr[x] = arr[x + 1]; arr[x + 1] = temp; } } System.out.println("第二次比较后:"); printArray(arr);*/ //排序 /* for (int x = 0; x < arr.length - 1; x++) { for (int y = 0; y < arr.length - 1 - x; y++) { if (arr[y] > arr[y + 1]) { int temp = arr[y]; arr[y] = arr[y + 1]; arr[y + 1] = temp; } } }*/ for (int i = 0; i < arr.length-1; i++) {//总共需要比较数组长度的 -1 次。(外层循环) for (int j = 0; j < arr.length-1-i; j++) {//每一个比较完毕后,下一次比较的时候就会少一个元素的比较(内层循环) if(arr[j] > arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } System.out.println("冒泡排序后:"); printArray(arr); } </span>
2、选择排序
1)原理:从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
- 从0索引开始,依次和后面元素比较,小的往前放
- 第一次是从 0 索引开始和其他元素比较
- 第二次是从 1 索引开始和其他元素比较
- 最后一次是数组长度-2 的元素 和数组长度-1的元素比较
2)分析图
3)代码实现
<span style="font-family:Arial;font-size:18px;"> /** * 选择排序 * 从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处 */ private void test2() { // 定义一个数组 int[] arr = { 24, 69, 80, 57, 13 }; System.out.println("排序前:"); printArray(arr); /* // 第一次 int x = 0; for (int y = x + 1; y < arr.length; y++) { if (arr[y] < arr[x]) { int temp = arr[x]; arr[x] = arr[y]; arr[y] = temp; } } System.out.println("第一次比较后:"); printArray(arr); // 第二次 x = 1; for (int y = x + 1; y < arr.length; y++) { if (arr[y] < arr[x]) { int temp = arr[x]; arr[x] = arr[y]; arr[y] = temp; } } System.out.println("第二次比较后:"); printArray(arr); */ for (int i = 0; i < arr.length-1; i++) {//从0索引开始, for (int j = i+1; j < arr.length; j++) {//依次和后面元素比较, if(arr[j] < arr[i] ){//小的往前放 int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } printArray(arr); } </span>
3、实例操作:把字符串中的字符进行排序。
<span style="font-family:Arial;font-size:18px;"> /* * 把字符串中的字符进行排序。 * 举例:"dacgebf" * 结果:"abcdefg" * * 分析: * A:定义一个字符串 * B:把字符串转换为字符数组 * C:把字符数组进行排序 * D:把排序后的字符数组转成字符串 * E:输出最后的字符串 */ private void test3() { String str = "mkloiuytrfdgsa"; char[] strArr = str.toCharArray(); //选择排序 /* for (int i = 0; i < strArr.length-1; i++) {//从0索引开始, for (int j = i+1; j < strArr.length; j++) {//依次和后面元素比较, if(strArr[j] < strArr[i]) {//小的往前放 char temp = strArr[j]; strArr[j] = strArr[i]; strArr[i] = temp; } } }*/ //冒泡排序 for (int i = 0; i < strArr.length-1; i++) {//每次从0开始,一共是length-1次 for (int j = 0; j < strArr.length-1-i; j++) {//每次就会少一次 if(strArr[j] > strArr[j+1]) {//大的往后放 char temp = strArr[j+1]; strArr[j+1] = strArr[j]; strArr[j] = temp; } } } String sortStr = String.valueOf(strArr); System.out.println(sortStr);//adfgiklmorstuy } </span>
(二)查找算法
1、基本查找算法
1)对象:针对没有顺序的数组
2)方法:循环整个数组,依次比较
3)代码实现:
<span style="font-family:Arial;font-size:18px;"> /** * 查找 * 基本查找:数组元素无序(从头找到尾) */ private void test4() { //定义一个数组 int[] arr = {55,22,11,44,33,88,66};//没顺序的数组 int a = 33; int index = -1; for (int i = 0; i < arr.length; i++) {//循环整个数组,依次比较 if(arr[i]==a) { System.out.println("索引为" + i); index = i; break; } } if(index == -1){ System.out.println("没找到...."); } } </span>
2、二分查找算法
1)对象:针对有顺序的数组
2)方法:
- 拿中间索引的值和要查找的值进行比较,相等,就返回当前的中间索引 。
- 大,左边找 max = mid - 1; (中间值大,向左找;这时最大值为这个(中间值-1),最小值为0)
- 小,右边找 min = mid + 1; (中间值小,向右找;这时最大值为(length -1),最小值为(中间值+1))
- 再计算中间索引,然后再比较。
3)分析图:
4)代码实现
<span style="font-family:Arial;font-size:18px;"> /** * 二分查找 * * 分析: * A:定义最大索引,最小索引 * B:计算出中间索引 * C:拿中间索引的值和要查找的值进行比较 * 相等:就返回当前的中间索引 * 不相等: * 大 左边找 * 小 右边找 * D:重新计算出中间索引 * 大 左边找 * max = mid - 1; * 小 右边找 * min = mid + 1; * E:回到B */ public void test5() { int[] arr = {11,22,33,44,55,66,77}; int value = 0; //定义最大索引,最小索引 int max = arr.length -1; int min = 0; //计算出中间索引 int mid = (max +min)/2; //拿中间索引的值和要查找的值进行比较 while(arr[mid] != value){ if(arr[mid]>value){//中间值大,向左找;这时最大值为这个(中间值-1),最小值为0 max = mid - 1; }else if(arr[mid]<value){//中间值小,向右找;这时最大值为(length -1),最小值为(中间值+1) min = mid + 1; } //加入判断 if(min > max){ mid = -1; break;//找不到 } mid = (max +min)/2; } System.out.println("二分查找后的结果: "+ mid); } </span>
5)注意问题:一个无序数组,先排序,再使用二分查找,这是不行的。
- 因为数组本身是无序的,所以这种情况下的查找不能使用二分查找。
- 因为先排序后,已经改变了最原始的元素索引,再查找出来的索引不是原有数组的索引值了。
<span style="font-family:Arial;font-size:18px;">package array; /** * * @Title: 使用二分排序的问题 * @Description: * @Copyright: Copyright (c) 2015 * @Company: * * @author: SAM-SHO * @version: 1.0 * @CreateDate:Apr 9, 2015 */ /* * 注意:下面这种做法是有问题的。 * 因为数组本身是无序的,所以这种情况下的查找不能使用二分查找。 * 你先排序了,但是你排序的时候已经改变了我最原始的元素索引,所以查找出来的不是原有需要的索引了。 */ public class ArrayDemo2 { public static void main(String[] args) { // 定义数组 int[] arr = { 24, 69, 80, 57, 13 }; // 先排序 bubbleSort(arr); // 后查找 int index = getIndex(arr, 80); System.out.println("index:" + index); } // 冒泡排序代码 public static void bubbleSort(int[] arr) { for (int x = 0; x < arr.length - 1; x++) { for (int y = 0; y < arr.length - 1 - x; y++) { if (arr[y] > arr[y + 1]) { int temp = arr[y]; arr[y] = arr[y + 1]; arr[y + 1] = temp; } } } } // 二分查找 public static int getIndex(int[] arr, int value) { // 定义最大索引,最小索引 int max = arr.length - 1; int min = 0; // 计算出中间索引 int mid = (max + min) / 2; // 拿中间索引的值和要查找的值进行比较 while (arr[mid] != value) { if (arr[mid] > value) { max = mid - 1; } else if (arr[mid] < value) { min = mid + 1; } // 加入判断 if (min > max) { return -1; } mid = (max + min) / 2; } return mid; } } </span>
(三)数组工具类
1、Arrays
1)把数组转成字符串:public static String toString(int[] a)
2)对数组进行排序:public static void sort(int[] a)
- 内部使用快速排序
3)二分查找:public static int binarySearch(int[] a,int key)
4)数组复制:copyOf 和 copyOfRange
<span style="font-family:Arial;font-size:18px;">package array; import java.util.Arrays; /** * * @Title: Arrays工具类的使用 * @Description: * @Copyright: Copyright (c) 2015 * @Company: * * @author: SAM-SHO * @version: 1.0 * @CreateDate:Apr 9, 2015 */ /* * Arrays:针对数组进行操作的工具类。比如说排序和查找。 * 1:public static String toString(int[] a) 把数组转成字符串 * 2:public static void sort(int[] a) 对数组进行排序 * 3:public static int binarySearch(int[] a,int key) 二分查找 */ public class ArraysDemo { public static void main(String[] args) { // 定义一个数组 int[] arr = { 24, 69, 80, 57, 13 }; // public static String toString(int[] a) 把数组转成字符串 System.out.println("排序前:" + Arrays.toString(arr)); // public static void sort(int[] a) 对数组进行排序 Arrays.sort(arr); System.out.println("排序后:" + Arrays.toString(arr)); // [13, 24, 57, 69, 80] // public static int binarySearch(int[] a,int key) 二分查找 System.out.println("binarySearch:" + Arrays.binarySearch(arr, 57)); System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577)); } }</span>
2、Array-反射使用