Arrays类
- 1. 概述
- 2. 常见方法
- 3. sort 方法的自定义排序
- 4. 代码示例
- 5. 输出结果
- 6. 注意事项
1. 概述
Arrays类是Java中的一个工具类,位于java.util包中。
它提供了一组静态方法,用于操作数组。通过Arrays类,我们可以对数组进行复制、填充、排序以及查找等常见操作。
Arrays类的方法主要包括以下几个方面:
-
数组拷贝:提供了copyOf()和copyOfRange()方法,用于将原数组复制到新数组中,并可以指定拷贝的范围。
-
数组填充:通过fill()方法,可以将数组中的所有元素填充为指定的值。
-
数组排序:使用sort()方法,可以对数组进行排序。sort()方法有两个版本,一个是使用默认规则进行排序,另一个是可以指定排序规则。
-
数组查找:提供了binarySearch()方法,使用二分查找法在数组中查找指定的元素。
2. 常见方法
方法 | 功能 |
---|---|
public static String toString(数组) | 将数组拼接成一个字符串 |
public static int binarySearch(数组,查找的元素) | 使用二分查找法在数组中查找元素 |
public static int[] copyOf(原数组,新数组长度) | 拷贝数组并指定新数组的长度 |
public static int[] copyOfRange(原数组,起始索引,结束索引) | 拷贝数组的指定范围到新数组中 |
public static void fill(数组,元素) | 将数组中的所有元素填充为指定元素 |
public static void sort(数组) | 使用默认规则对数组进行排序 |
public static void sort(数组,排序规则) | 使用指定规则对数组进行排序 |
注意:
-
public static int binarySearch(数组,查找的元素) : 二分查找法查找元素
-
细节1:二分查找的前提:数组中的元素必须是有序的,且数组中的元素必须是升序的
-
细节2:
-
如果要查找的元素存在,则返回的是真实的索引值;
-
如果要查找的元素不存在,则返回的是
-插入点 -1
。 -
-1
的原因:如果此时,我们要查找数字0
(假如0在数组中并不存在),那么如果返回的值是-插入点,那么则为-0
;有的人认为-0
等同于0
,因此为避免这种情况出现,Java规定如果要查找的元素不存在,则返回的是-插入点 -1
。
-
-
-
public static int[] copyOf(原数组,新数组长度) :拷贝数组
-
细节:
-
当新数组的长度小于原数组的长度时,会部分拷贝原数组的元素
-
当新数组的长度等于原数组的长度时,会全部拷贝原数组的元素
-
当新数组的长度大于原数组的长度时,会全部拷贝原数组的元素,剩余位置补上默认初始化(例如,int类型的数组剩余位置补0)
-
-
-
public static int[] copyOfRange(原数组,起始索引,结束索引) : 拷贝数组(指定范围)
-
细节:
- 包头不包尾,包左不包右
-
-
public static void sort(数组) :按照默认方式进行排序
-
细节:
- 默认情况下,给基本数据类型进行升序操作。底层使用的是快速排序
-
-
public static void sort(数组,排序规则) : 按照指定的规则排序
-
参数一:要排序的数组
-
参数二:排序的规则
-
细节:
-
只能给引用数据类型的数组进行排序,如果数组是基本数据类型的话,需要变成其对应的包装类
-
第二个参数是一个接口,所以我们在调用方法的时候,需要传递这个接口的实现类对象,作为排序的规则。
-
但是这个实现类一般只用使用一次,因此没有必要单独写一个类,直接采用匿名内部类的方法就可以了
-
-
-
底层原理:利用插入排序 + 二分查找的方法进行排序的
- 默认把 0 索引的数据作为有序序列,1索引及其以后得所有数据都作为无序序列。
- 遍历无序序列,得到里面的每一个元素,把得到的元素往有序序列中插入,在插入时,是利用二分查找的方法确认该元素的插入点,然后拿着该元素与插入点的元素进行比较。(比较的方式与之前不同,该比较的方式是从前往后遍历),比较的规则是compare方法的方法体。
-
如果方法的返回值是负数,拿着该元素继续跟前面的数据进行比较
-
如果方法的返回值是正数,拿着该元素继续跟后面的数据进行比较
-
如果方法的返回值是0,拿着该元素继续跟后面的数据进行比较
-
- 直到能确定该元素的位置为止
-
compare方法的形参参数:
- 参数一 o1:表示在无序序列中,遍历得到的每一个元素
- 参数二 o2:有序序列中的元素
- 返回值:
-
负数:表示当前要插入的元素是小的,放前面
-
正数:表示当前要插入的元素是大的,放后面
-
- 0:表示当前要插入的元素跟该位置的元素是一样的,放后面
-
o1-o2:升序排列
-
o2-o1:降序排列
-
3. sort 方法的自定义排序
由于Arrays类是一个final类,无法被继承,因此不允许对sort()方法进行重写。
然而,如果想要实现自定义的排序逻辑,可以通过传递一个实现了Comparator接口的自定义比较器对象来调用sort()方法,这样可以指定排序时使用的比较规则。这种方式并不是重写,而是通过回调方法(Comparator接口中的compare()方法)来实现自定义的排序行为。
当我们调用Arrays.sort()
方法时,根据传入的参数不同,会调用不同的重载方法。
-
public static void sort(T[] a)
- 功能:用于对传入的数组进行排序。
- 参数:
a
是要排序的数组,类型为T[]
,表示一个指定元素类型的数组。 - 排序规则:默认使用数组元素的自然顺序进行排序。如果数组中的元素是基本数据类型,会使用对应的包装类的自然顺序进行排序。
- 返回值:无。
- 示例:
Integer[] numbers = {5, 2, 8, 1, 9}; Arrays.sort(numbers); // 数组将被排序为:{1, 2, 5, 8, 9}
-
public static void sort(T[] a, Comparator<? super T> c)
- 功能:用于对传入的数组进行排序,使用自定义的排序规则。
- 参数:
a
是要排序的数组,类型为T[]
,表示一个指定元素类型的数组。c
是一个Comparator
对象,用于定义元素的比较规则。
- 排序规则:根据
Comparator
对象的定义进行排序。 - 返回值:无。
- 示例:
String[] names = {"John", "Alice", "Bob", "David"}; Arrays.sort(names, (s1, s2) -> s1.compareToIgnoreCase(s2)); // 数组将被排序为:{"Alice", "Bob", "David", "John"}
4. 代码示例
package text.text02;
import java.util.Arrays;
import java.util.Comparator;
/*
Arrays类:
public static String toString(数组) 把数组拼接成一个字符串
public static int binarySearch(数组,查找的元素) 二分查找法查找元素
细节1:二分查找的前提:数组中的元素必须是有序的,且数组中的元素必须是升序的
细节2:如果要查找的元素存在,则返回的是真实的索引值
如果要查找的元素不存在,则返回的是 -插入点-1
-1的原因:如果此时,我们要查找数字0(假如0在数组中并不存在),那么如果返回的值是-插入点,那么则为-0;有的人认为-0等同于0,因此为避免这种情况出现,Java规定如果要查找的元素不存在,则返回的是 -插入点-1。
public static int[] copyOf(原数组,新数组长度) 拷贝数组
细节:当新数组的长度小于原数组的长度时,会部分拷贝原数组的元素
当新数组的长度等于原数组的长度时,会全部拷贝原数组的元素
当新数组的长度大于原数组的长度时,会全部拷贝原数组的元素,剩余位置补上默认初始化(例如,int类型的数组剩余位置补0)
public static int[] copyOfRange(原数组,起始索引,结束索引) 拷贝数组(指定范围)
细节:包头不包尾,包左不包右
public static void fill(数组,元素) 填充数组
public static void sort(数组) 按照默认方式进行排序
细节:默认情况下,给基本数据类型进行升序操作。底层使用的是快速排序
public static void sort(数组,排序规则) 按照指定的规则排序
参数一:要排序的数组
参数二:排序的规则
细节:只能给引用数据类型的数组进行排序,如果数组是基本数据类型的话,需要变成其对应的包装类
第二个参数是一个接口,所以我们在调用方法的时候,需要传递这个接口的实现类对象,作为排序的规则。
但是这个实现类一般只用使用一次,因此没有必要单独写一个类,直接采用匿名内部类的方法就可以了
底层原理:利用插入排序 + 二分查找的方法进行排序的
默认把 0 索引的数据作为有序序列,1索引及其以后得所有数据都作为无序序列。
遍历无序序列,得到里面的每一个元素,把得到的元素往有序序列中插入,在插入时,是利用二分查找的方法确认该元素的插入点,然后拿着该元素与插入点的元素进行比较。(比较的方式与之前不同,该比较的方式是从前往后遍历),比较的规则是compare方法的方法体。
如果方法的返回值是负数,拿着该元素继续跟前面的数据进行比较
如果方法的返回值是正数,拿着该元素继续跟后面的数据进行比较
如果方法的返回值是0,拿着该元素继续跟后面的数据进行比较
直到能确定该元素的位置为止
compare方法的形参参数:
参数一 o1:表示在无序序列中,遍历得到的每一个元素
参数二 o2:有序序列中的元素
返回值:
负数:表示当前要插入的元素是小的,放前面
正数:表示当前要插入的元素是大的,放后面
0:表示当前要插入的元素跟该位置的元素是一样的,放后面
o1-o2:升序排列
o2-o1:降序排列
*/
public class text16 {
public static void main(String[] args) {
int[] arr1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] arr2 = {10, 5, 3, 4, 7, 8, 2, 9, 1, 6, 0};
//public static String toString(数组):把数组拼接成一个字符串
System.out.println("=============== toString(数组):把数组拼接成一个字符串 ===============");
String str1 = Arrays.toString(arr1);
System.out.println(str1); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println();
//public static int binarySearch(数组,查找的元素):二分查找法查找元素
//细节1:二分查找的前提:数组中的元素必须是有序的,且数组中的元素必须是升序的
//细节2:如果要查找的元素存在,则返回的是真实的索引值
// 如果要查找的元素不存在,则返回的是 -插入点-1
//-1的原因:如果此时,我们要查找数字0(假如0在数组中并不存在),那么如果返回的值是-插入点,那么则为-0;有的人认为-0等同于0,因此为避免这种情况出现,则Java规定如果要查找的元素不存在,则返回的是 -插入点-1。
System.out.println("=============== binarySearch(数组,查找的元素):二分查找法查找元素 ===============");
int int1 = Arrays.binarySearch(arr1, 5);
int int2 = Arrays.binarySearch(arr1, 10);
int int3 = Arrays.binarySearch(arr1, 15);
System.out.println(int1); //5
System.out.println(int2); //10
System.out.println(int3); //-12
System.out.println();
//public static int[] copyOf(原数组,新数组长度):拷贝数组
//细节:当新数组的长度小于原数组的长度时,会部分拷贝原数组的元素
// 当新数组的长度等于原数组的长度时,会全部拷贝原数组的元素
// 当新数组的长度大于原数组的长度时,会全部拷贝原数组的元素,剩余位置补上默认初始化(例如,int类型的数组剩余位置补0)
System.out.println("=============== copyOf(原数组,新数组长度):拷贝数组 ===============");
int[] int4 = Arrays.copyOf(arr1, 6);
int[] int5 = Arrays.copyOf(arr1, 11);
int[] int6 = Arrays.copyOf(arr1, 20);
System.out.println(Arrays.toString(int4)); //[0, 1, 2, 3, 4, 5]
System.out.println(Arrays.toString(int5)); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(Arrays.toString(int6)); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0]
System.out.println();
//public static int[] copyOfRange(原数组,起始索引,结束索引):拷贝数组(指定范围)
//细节:包头不包尾,包左不包右
System.out.println("=============== copyOfRange(原数组,起始索引,结束索引):拷贝数组(指定范围) ===============");
int[] int7 = Arrays.copyOfRange(arr1, 0, 10);
int[] int8 = Arrays.copyOfRange(arr1, 0, 11);
System.out.println(Arrays.toString(int7)); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
System.out.println(Arrays.toString(int8)); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println();
//public static void fill(数组,元素):填充数组
System.out.println("=============== fill(数组,元素):填充数组 ===============");
Arrays.fill(arr1, 20);
System.out.println(Arrays.toString(arr1)); //[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
System.out.println();
//public static void sort(数组):按照默认方式进行排序
//细节:默认情况下,给基本数据类型进行升序操作。底层使用的是快速排序
System.out.println("=============== sort(数组):按照默认方式进行排序 ===============");
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2)); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println();
//public static void sort(数组,排序规则):按照指定的规则排序
//参数一:要排序的数组
//参数二:排序的规则
//细节:只能给引用数据类型的数组进行排序,如果数组是基本数据类型的话,需要变成其对应的包装类
// 第二个参数是一个接口,所以我们在调用方法的时候,需要传递这个接口的实现类对象,作为排序的规则。
// 但是这个实现类一般只用使用一次,因此没有必要单独写一个类,直接采用匿名内部类的方法就可以了
//底层原理:利用插入排序 + 二分查找的方法进行排序的
//默认把 0 索引的数据作为有序序列,1索引及其以后得所有数据都作为无序序列。
//遍历无序序列,得到里面的每一个元素,把得到的元素往有序序列中插入,在插入时,是利用二分查找的方法确认该元素的插入点,然后拿着该元素与插入点的元素进行比较。(比较的方式与之前不同,该比较的方式是从前往后遍历),比较的规则是compare方法的方法体。
//如果方法的返回值是负数,拿着该元素继续跟前面的数据进行比较
//如果方法的返回值是正数,拿着该元素继续跟后面的数据进行比较
//如果方法的返回值是0,拿着该元素继续跟后面的数据进行比较
//直到能确定该元素的位置为止
System.out.println("=============== sort(数组,排序规则):按照指定的规则排序 ===============");
Integer[] arr3 = {2, 3, 5, 6, 8, 9, 1, 0, 4, 10, 7};
Arrays.sort(arr3, new Comparator<Integer>() {
//compare方法的形参参数:
//参数一 o1:表示在无序序列中,遍历得到的每一个元素
//参数二 o2:有序序列中的元素
//返回值:
//负数:表示当前要插入的元素是小的,放前面
//正数:表示当前要插入的元素是大的,放后面
//0:表示当前要插入的元素跟该位置的元素是一样的,放后面
//o1-o2:升序排列
//o2-o1:降序排列
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
System.out.println("升序排序:" + Arrays.toString(arr3)); //升序排序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Arrays.sort(arr3, new Comparator<Integer>() {
//compare方法的形参参数:
//参数一 o1:表示在无序序列中,遍历得到的每一个元素
//参数二 o2:有序序列中的元素
//返回值:
//负数:表示当前要插入的元素是小的,放前面
//正数:表示当前要插入的元素是大的,放后面
//0:表示当前要插入的元素跟该位置的元素是一样的,放后面
//o1-o2:升序排列
//o2-o1:降序排列
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println("降序排序:" + Arrays.toString(arr3)); //降序排序:[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
}
}
5. 输出结果
-
public static String toString(数组):把数组拼接成一个字符串
-
public static int binarySearch(数组,查找的元素):二分查找法查找元素
-
public static int[] copyOf(原数组,新数组长度):拷贝数组
-
public static int[] copyOfRange(原数组,起始索引,结束索引):拷贝数组(指定范围)
-
public static void fill(数组,元素):填充数组
-
public static void sort(数组):按照默认方式进行排序
-
public static void sort(数组,排序规则):按照指定的规则排序
6. 注意事项
-
Arrays
类中的方法都是静态方法,无需实例化对象即可直接调用。 -
Arrays
类的方法通常针对数组进行操作,因此在使用这些方法之前,需要先创建合适的数组对象,并将数据存储在数组中。 -
使用
Arrays.copyOf()
或Arrays.copyOfRange()
方法时,要确保目标数组的长度足够存储源数组或指定的范围内的元素。否则,可能会出现ArrayIndexOutOfBoundsException
错误。 -
Arrays.toString()
和Arrays.deepToString()
方法可以将数组转换为字符串,方便打印和调试。但需要注意,这些方法将直接使用数组的toString()
方法来获取字符串表示形式,因此自定义的类需要重写toString()
方法才能得到正确的输出。 -
当使用
Arrays.sort()
方法对数组进行排序时,需要注意数组元素的可比较性。如果数组元素是自定义的类对象,需要确保该类实现了Comparable
接口,或者使用重载方法并传入自定义的Comparator
对象来指定元素的比较规则。