蓝桥杯JAVA-2.数组操作

本文最后更新于:December 14, 2021 pm

积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。

目录

1.数组

1.1 声明创建数组

1
2
3
int[] a=new int[10]; //首选
int aa[]=new int[10]; //C/C++形式,效果相同,但不是最好的选择
int[] b={2,5,14,5,3}; //创建并初始化

1.2 多维数组

多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

1.2.1 固定空间

1
int[][] b=new int[5][2];

1.2.2 动态分配

可以为每一个一维数组分配不同大小的空间。

1
2
3
4
5
6
7
8
String s[][] = new String[2][]; //这里的String 可以换成其他类型
s[0] = new String[2];//为最高维分配引用空间,也就是为最高维限制其能保存数据的最长的长度,下同。
s[1] = new String[3];
s[0][0] = new String("Good"); //为其每个数组元素单独分配空间,下同
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");

1.3 数组复制

1 数组的clone()方法

clone()方法我们在数组中是找不到的,它是object的方法,它的源码:

1
2
3
4
protected native Object clone() throws CloneNotSupportedException;
/*
看到了修饰符native,说明是由c或者c++实现的,它的优点是速度快,它返回了object对象,所以使用的时候需要用对象接收返回值。native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。
*/

使用方法:

1
2
3
4
5
6
7
int[] a={2,4,2,9,1,3,6,5,65,56,4,5,6,5}
int[] b= new int[50];
b = a.clone();
System.out.println(Arrays.toString(b));
/*
[2, 4, 2, 9, 1, 3, 6, 5, 65, 56, 4, 5, 6, 5]
*/

2 System.arraycopy()方法(重点)

使用:public static native void arraycopy(Object src,int srcPos,Object dest,int desPos,int length)

需要注意,新的数组多余的会自动补0。且System.arraycopy()比clone()方法快。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int[] a={2,4,2,9,1,3,6,5,65,56,4,5,6,5};
int[] b = new int[20];
System.arraycopy(a,0,b,0,10);
System.out.println(Arrays.toString(b)); //

System.arraycopy(a,0,b,0,a.length);
System.out.println(Arrays.toString(a)); //
System.out.println(Arrays.toString(b)); //

System.out.println(b.length);
/*
[2, 4, 2, 9, 1, 3, 6, 5, 65, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[2, 4, 2, 9, 1, 3, 6, 5, 65, 56, 4, 5, 6, 5]
[2, 4, 2, 9, 1, 3, 6, 5, 65, 56, 4, 5, 6, 5, 0, 0, 0, 0, 0, 0]
20(包括了多余的0,即等于数组开的大小)
*/
源码
1
2
3
public static native void arraycopy(Object src,  int  srcPos,
Object dest, int destPos,
int length);

3 Arrays类的copyOf()方法和copyOfRange()方法

1 Arrays.copyOf()方法

很显然,
如果newLength小于源数组的长度,则将源数组的前面若干个元素复制到目标数组。
如果newLength大于源数组的长度,则将源数组的所有元素复制到目标数组(这种方式的数组需要注意,见样例)。

它在方法内部调用了System.arraycopy(),只是相当于重写了一下,换了一个名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int[] a={2,4,2,9,1,3,6,5};
int[] b = new int[303];
b = Arrays.copyOf(a,5);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));

b = Arrays.copyOf(a,15);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
System.out.println(b.length);
/*
[2, 4, 2, 9, 1, 3, 6, 5]
[2, 4, 2, 9, 1]

[2, 4, 2, 9, 1, 3, 6, 5]
[2, 4, 2, 9, 1, 3, 6, 5, 0, 0, 0, 0, 0, 0, 0]
15(包括了多余的0)
*/
源码
1
2
3
4
5
6
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
2 copyOfRange()方法

1
2
3
4
5
6
7
8
9
int[] a={2,4,2,9,1,3,6,5,43,34,2,1};
int[] b = new int[303];
b = Arrays.copyOfRange(a,1,8);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
/*
[2, 4, 2, 9, 1, 3, 6, 5, 43, 34, 2, 1]
[4, 2, 9, 1, 3, 6, 5]
*/
源码
1
2
3
4
5
6
7
8
9
public static int[] copyOfRange(int[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
int[] copy = new int[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}

可自行查看这些方法的源码。

1.4 数组相关操作

1.4.1 Arrays 类

java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
具有一下功能:

1.给数组赋值:通过 fill 方法。
2.对数组排序:通过 sort 方法,按升序。sort只提供升序排序,并不支持降序排序。但可以倒序输出即可。如果一定要用 sort 实现降序排序,可以参考《java知识拓展》博文。
3.比较数组:通过 equals 方法比较数组中元素值是否相等。
4.查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

Java中Arrays类的常用方法

1.Arrays类位于 java.util 包中,主要包含了操作数组的各种方法。

1
import java.util.Arrays;

2.Arrays.fill(); //填充数组

1
2
3
4
5
6
7
8
9
10
11
12
13
//实用一
int[] arr = new int[5];//新建一个大小为5的数组
Arrays.fill(arr,4);//给所有值赋值4
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[4, 4, 4, 4, 4]

//实用二
int[] arr = new int[5];//新建一个大小为5的数组
Arrays.fill(arr,2,4,6);//[2,4) 下标从0开始。下标为2(包括)到下标为4(不包括)全部赋值为6
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[0, 0, 6, 6, 0]

3.Arrays.sort(); //数组排序

Arrays类有一个静态方法sort,利用这个方法可传入要排序的数组进去排序,因为传入的是一个数组的引用,所以排序完成的结果也通过这个引用来更改数组。

1.数字排序

1
2
3
int[] intArray = new int[] { 4, 1, 3, -23 };
Arrays.sort(intArray);
//输出: [-23, 1, 3, 4]

2.字符串排序,先大写后小写
因为大写字母的ASCII码比小写字母的小。

1
2
3
String[] strArray = new String[] { “z”, “a”, “C” };
Arrays.sort(strArray);
//输出: [C, a, z]

3.严格按字母表顺序排序,也就是忽略大小写排序

1
2
3
String[] strArray = new String[] { “z”, “a”, “C” };
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
//输出: [a, C, z]

4.反向排序
在数字数组中可以实现降序排序。大写字母的ASCII码比小写字母的小。需要导包 import java.util.Collections; 或者使用import java.util.*;。

1
2
3
String[] strArray = new String[] { “z”, “a”, “C” };
Arrays.sort(strArray, Collections.reverseOrder());
//输出:[z, a, C]

5.忽略大小写反向排序
可以理解成把所有的字母转换成对应小写字母或大写字母。转换成一种进行比较。
但是,当数组中有一个大写字母C和一个小写字母c时,大写字母C会在小写字母c前面,其他同理。

1
2
3
4
String[] strArray = new String[] { “z”, “a”, “C” };
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
Collections.reverse(Arrays.asList(strArray));
//输出: [z, C, a]

6.选择数组指定位置进行排序

1
2
3
4
5
int[] arr = {3,2,1,5,4};
Arrays.sort(arr,0,3);//[0,3),小标0开始。 从小标0开始(包括)到下标为3(不包括)的区间进行排序
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[1, 2, 3, 5, 4]

4.Arrays.toString(); //将数组中的内容全部打印出来

1
2
3
4
5
6
7
   int[] arr = {3,2,1,5,4};
System.out.print(arr);//直接将数组打印输出
//输出:[I@7852e922 (数组的地址)

String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
//System.out.print(str);
//输出:[3, 2, 1, 5, 4]

5.Arrays.equals(); //比较数组元素是否相等

1
2
3
4
5
int[] arr1 = {1,2,3};
int[] arr2 = {1,2,3};
System.out.println(Arrays.equals(arr1,arr2));
//输出:true
//如果是arr1.equals(arr2),则返回false,因为equals比较的是两个对象的地址,不是里面的数,而Arrays.equals重写了equals,所以,这里能比较元素是否相等。至于‘=’与equals的区别可见另一篇博文《java知识拓展》。

6.Arrays.binarySearch(); //二分查找法找指定元素的索引值(下标)

数组一定是排好序的,否则会出错。找到元素,只会返回最后一个位置。

1
2
3
int[] arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 30));
//输出:2 (下标索引值从0开始)
1
2
3
int[] arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 36));
//输出:-4 (找不到元素,返回-x,从-1开始数,如题,返回-4)
1
2
3
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 0,3,30));
//输出:2 (从0到3位(不包括)找30,找到了,在第2位,返回2)
1
2
3
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 0,3,40));
//输出:-4 (从0到3位(不包括)找40,找不到,从-1开始数,返回-4)

7.Arrays.copeOf() 和Arrays.copeOfRange(); //截取数组

1
2
3
4
5
int[] arr = {10,20,30,40,50};
int[] arr1 = Arrays.copyOf(arr, 3);//[0,3)。下标从0开始,到下标为3为止(不包括3)。
String str = Arrays.toString(arr1); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[10, 20, 30] (截取arr数组的3个元素赋值给姓数组arr1)
1
2
3
4
5
int []arr = {10,20,30,40,50};
int []arr1 = Arrays.copyOfRange(arr,1,3);
String str = Arrays.toString(arr1); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[20, 30] (从第1位(0开始)截取到第3位(不包括)

1.4.2 数组容量扩充

数组容量如果不够用可以使用 Arrays.copyOf() 进行扩容。

1
Array.copy(E[] e,newLength);

其中第一个形参指的是需要扩容的数组,后面是扩容后的大小。其内部实现其实是使用了 System.arrayCopy(); 在内部重新创建一个长度为 newLength 类型是 E 的数组。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.Arrays;  
public class Main {
public static void main(String[] args) {
int[] a= {10,20,30,40,50};
a= Arrays.copyOf(a,a.length+1);
for(int i=0;i<a.length;i++) {
System.out.println(a[i]);
}
}
}
//输出结果
10 20 30 40 50 0 //默认补充0

1.4.3 数组中的常见异常

1数组下标越界(ArrayIndexOutOfBoundsException)

错误代码:

1
2
3
4
5
6
7
8
int[] arr = new int[]{1,2,3,4,5};
for(int i=0;i<=arr.length;++i){//数组的存值,下标是前闭后开的,即:存5个数,则下标是[0,5)的。是不包含5的。
System.out.println(arr[i]);
}
System.out.println(arr[-2]); //下标越界。
//当出现异常之后,后面的代码是不能运行的。如:
System.out.println(arr[-2]); //下标越界。
System.out.println("hello world!");//不会输出
2空指针异常(NullPointerException)

错误代码一:

1
2
3
int[] arr = new int[]{1,2,3};
arr = null;//注释掉这句代码则可以正常运行。
System.out.println(arr[0]);//会出现异常。

错误代码二:

1
2
3
int[][] arr = new int[4][];
System.out.println(arr[0]);//执行这句代码不会出错。会输出null
System.out.println(arr[0][0]);//执行会出现空指针异常

错误代码三:

1
2
3
4
String[] arr = new String[]{"AA","BB","CC"};
System.out.println(arr[0].toString());//输出 AA
arr[0] = null;
System.out.println(arr[0].toString());//会出现空指针异常