目录
概述
Arrays类在Java.util包中,因此全类名为 Java.util.Arrays.在此类中,定义了很多常见的数组操作方法,并且这些方法基本都是静态的,我们需要通过类名直接调用,即Arrays.方法名().
常用方法
equals()
● 比较两个非同一数组是否相等,而数组本身的equals判断另一个数组是否它本身。
● 声明:public static boolean equals(type[]a,type[]a2)
● 参数的类型可以是原生数据类型和引用类型的任意一种类型。
● 返回:如果两个相等,则返回true,否则返回false
//声明俩个数组a1,a2
int[] a1 = {1,1,1,1,1};
int[] a2 = {1,1,1,1,1};
//输出Arrays.equals(a1,a2)结果,此方法比较俩个数组中的元素是否相等
System.out.println(Arrays.equals(a1,a2));//结果为true
源代码
//此方法被static修饰,调用时需要通过类名调用
public static boolean equals(int[] a, int[] a2) {
if (a==a2)//此时比较俩个数组的地址,如果相等表明是同一个对象,直接返回true;
return true;
if (a==null || a2==null) //如果俩个数组有一个为空的话直接返回false
return false;
int length = a.length;
if (a2.length != length)//比较数组长度,如果不相等,直接返回false
return false;
//以上都不满足需要将数组元素一一比较,有不相等的元素返回false,都相等返回true;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
filll()
此方法可以对数组指定位置填充指定元素.
public static void main(String[] args) {
int[] arr = new int[5];//创建一个新的数组
Arrays.fill(arr,2);//用2填充arr数组,没有指定区间,默认填充整个数组
System.out.println(Arrays.toString(arr)); //结果 : [2, 2, 2, 2, 2]
Arrays.fill(arr,0,3, 4);//用4填充arr数组中[0,3)的元素,区间不包括toIndex(右区间)
System.out.println(Arrays.toString(arr)); //结果 : [4, 4, 4, 2, 2]
}
sort()
此方法可以对指定类型(除boolean外的其他所有原生数据类型)数组指定区间进行升序排序.
● 作用于数组的所有元素(指定区间为整个数组)
public static void main(String[] args) {
int[] arr = {1,3,2,5,4};
Arrays.sort(arr);//没有指定区间,将对整个数组进行排序
System.out.println(Arrays.toString(arr));//输出结果 : {1,2,3,4,5}
}
● 作用于数组指定范围内的元素
int[] a = {1,3,2,5,4};
Arrays.sort(a,0,3);// [fromIndex,toIndex)为指定区间,其中toIndex为开区间不包括toIndex
System.out.println(Arrays.toString(a)); //输出结果 : {1, 2, 3, 5, 4}
● 自定义对象排序
在数组中我们可以放任意类型的数据(基本数据类型以及引用数据类型),但是不是任何数据都可以用sort排序,因为这些数据不具有可比较性,Arrays不知道谁的优先级更高.所以要想使用排序,必须告诉Arrays优先级的比较,在Java中,有一个Comparable接口,具有比较排序的功能.如果我们使用Integer类型数组就可以排序,因为Integer类实现了Comparable接口.
public final class Integer
extends Number
implements Comparable<Integer> //实现Comparable接口
自定义类实现Comparable接口
我们自己创建一个类User,并且创建一个User的数组,这时使用sort方法时就会报错 Exception in thread "main" java.lang.ClassCastException(类型转换错误)
//没有实现Comparable接口
public class User {
private int id;
private String account;
private String passeord;
public User() {
}
public User(int id, String account, String passeord) {
this.id = id;
this.account = account;
this.passeord = passeord;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPasseord() {
return passeord;
}
public void setPasseord(String passeord) {
this.passeord = passeord;
}
}
public static void main(String[] args) {
User user1 = new User(1,"111", "111");
User user2 = new User(2,"111", "111");
User user3 = new User(3,"111", "111");
User[] users = {user1,user2,user3};
Arrays.sort(users);//由于没有实现Comparable接口,所以会报错
System.out.println(Arrays.toString(users));
}
Arrays.sort()部分源码:
sort()的底层会调用这个mergeSort方法,上面的User类没有实现Comparable接口,因此在下面这行代码中强制类型转换会报错,因为User和Comparable没有关系.
重写compareTo方法
上面源码中也可以看出,在元素比较时,调用comparaTo()这个方法.我们自己的类继承Comparable接口后,要重写compareTo方法,在方法中定义这个类的优先级比较(即比较的规则).重写之后sort方法在调用compareTo方法时会调用这个类重写的compareTo方法,就会根据我们定义的排序规则进行排序.
示例:
//实现Comparable接口
public class User implements Comparable<User>{
private int id;
private String account;
private String passeord;
public User() {
}
public User(int id, String account, String passeord) {
this.id = id;
this.account = account;
this.passeord = passeord;
}
//重写compareTo方法
@Override
public int compareTo(User user) {
return this.id - user.id; //用user的id大小进行排序
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", account='" + account + '\'' +
", passeord='" + passeord + '\'' +
'}';
}
public static void main(String[] args) {
User user1 = new User(1,"111", "111");
User user2 = new User(2,"111", "111");
User user3 = new User(3,"111", "111");
User[] users = {user1,user2,user3};
Arrays.sort(users);
System.out.println(Arrays.toString(users));
/**
* 运行结果 :
* [User{id=1, account='111', passeord='111'}, User{id=2, account='111', passeord='111'},
* User{id=3, account='111', passeord='111'}]
*/
}
}
binarySearch ()
此方法使用二分查找法查找我们需要找的值,并返回元素在数组中的最小索引(可能存在重复元素),没找到则会返回负数.
二分查找法是一种算法思想,又称为折半查找法,要使用这个算法,前提是保证查找的这个集合是有序的.
因此,使用此方法时,要注意数组是否为有序的.
源码:
该方法体就使用了二分查找法, 如果找到元素,会返回该元素第一次出现的索引,否则返回负数.
示例:
public static void main(String[] args) {
//创建一个有序数组
int[] a = {1,3,4,5,7,8,9};
/*查找元素6.在数组中不存在返回负数
a是查询的数组, 6是需要找的元素
*/
System.out.println(Arrays.binarySearch(a,6));// 返回 -5
//查找元素4在数组第2个位置,所以返回2
System.out.println(Arrays.binarySearch(a,4)); //返回 2
}
copyOf()方法
此方法将一个数组中的元素从索引0开始复制特定长度的元素到另一个数组中并返回.
示例:
public static void main(String[] args) {
int[] a = {1,3,4,5,7,8,9};
/*
Arrays.copyOf(a,5)
a 为原数组,会复制此数组中的元素
5 长度 ,从a中复制是个元素
返回一个相同类型的数组 赋给b
*/
int[] b = Arrays.copyOf(a,5);
System.out.println(Arrays.toString(b)); // [1, 3, 4, 5, 7]
}
源码:
源码中会调用这个被native修饰的方法,是调用操作系统的本地方法,比我们自己遍历数组进行复制效率更高.
复制数组的方法还有一个copyOfRange(),此方法中会传入from(开始索引)和to(结束索引),会复制原数组中[from,to]的元素到新数组.
public static void main(String[] args) {
int[] a = {1,3,4,5,7,8,9};
/*
Arrays.copyOf(a,5)
a 为原数组,会复制此数组中的元素
5 长度 ,从a中复制是个元素
返回一个相同类型的数组 赋给b
*/
int[] b = Arrays.copyOf(a,5);
int[] c = Arrays.copyOfRange(a,0,5);
System.out.println(Arrays.toString(b)); // [1, 3, 4, 5, 7]
System.out.println(Arrays.toString(c)); // [1, 3, 4, 5, 7] 和 b数组一样
}
理解:Arrays.copyOf(a,5) 和Arrays.copyOfRange(a,0,5)执行结果是一样的,Arrays.copyOf(a,5)可以理解为复制a中[0,5]的元素.并且在底层中,这俩个方法调用的同一个方法.
toString()
和Object的toString方法的功能一样,将数组的元素以特定的字符串的形式打印出来,但Arrays类中的toString()是Arrays提供的静态方法,通过Arrays类名调用,不属于方法重写.在上个示例输出时调用了此方法,如果不调用此方法,在输出时,会调用Object中的toString方法,输出数组的hash值.
输出示例