该类包含用于操作数组的各种方法(例如排序和搜索)。 此类还包含一个静态工厂,允许将数组视为列表。
java.util类库下的Arrays类,包含用于操作数组的一套static实用方法。其中常用的方法有:equals()用于比较讲个数组是否相等(deepEquals()用于多维数组);fill()方法可以填充整个数组;sort()用于对数组排序;binarySearch()用于在已经排序的数组中查找元素;toString()产生数组的String表示;HashCode()产生数组的散列码;Arrays.asList()接受任意的序列或数组作为参数并将其转换为List容器。
1、数组复制、填充
java标准类库提供有static方法System.arraycopy(),用它复制数组比用for循环复制块。而且System.arraycopy()针对所有类型做了重载。System.arraycopy()不会自动装箱和拆箱,两个数组必须具有相同的确切类型。
Arrays.copyOf()也可以对数组复制,根据新的数组长度返回一个数组。
public class ArraysTest {
public static void main(String[] args) {
int[] a = new int[8];
int[] b = new int[10];
Arrays.fill(a, 40);
Arrays.fill(b, 3,5,30);
System.out.println("数组a"+Arrays.toString(a));//数组a[40, 40, 40, 40, 40, 40, 40, 40]
System.out.println("数组b"+Arrays.toString(b));//数组b[0, 0, 0, 30, 30, 0, 0, 0, 0, 0]
System.arraycopy(a, 0, b, 0, a.length);
System.out.println("数组a复制到数组b"+Arrays.toString(b));//数组a复制到数组b[40, 40, 40, 40, 40, 40, 40, 40, 0, 0]
int[] ac =Arrays.copyOf(b, 6);
for (int i : ac) {
System.out.print(i+" ");//40 40 40 40 40 40
}
System.out.println();
int[] c =new int[10000000];
int[] d =new int[10000000];
int[] dd =new int[10000000];
Arrays.fill(c, 10);
double startd =System.currentTimeMillis();
System.arraycopy(c, 0, d, 0, c.length);
double endd =System.currentTimeMillis();
double startdd =System.currentTimeMillis();
dd = Arrays.copyOf(c,c.length);
double enddd =System.currentTimeMillis();
System.out.println("system:"+(endd-startd));
System.out.println("arrays:"+(enddd-startdd));
}
}
结果:
数组a[40, 40, 40, 40, 40, 40, 40, 40]
数组b[0, 0, 0, 30, 30, 0, 0, 0, 0, 0]
数组a复制到数组b[40, 40, 40, 40, 40, 40, 40, 40, 0, 0]
40 40 40 40 40 40
system:12.0
arrays:23.0
源码
fill()通过for循环对数组赋值。
public static void fill(int[] a, int val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
copyof() 这个方法内部也是调用的System.arraycopy()进行数组复制。
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;
}
System.arraycopy()是系统底层的本地方法,速度快。
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
2、数组的比较
Arrays类提供了重载后的equals()方法,用来比较整个数组。数组相等的条件是数组元素个数相等且对应位置的元素也相同。
public class ArraysTest {
public static void main(String[] args) {
int[] a = new int[10];
int[] b = new int[10];
int[] c = new int[10];
int[] d = new int[20];
Arrays.fill(a, 40);
Arrays.fill(b, 40);
Arrays.fill(c, 30);
Arrays.fill(d, 40);
System.out.println(Arrays.equals(a, b));//true 数组长度相等,元素相同
System.out.println(Arrays.equals(a, c));//false 数组长度相等,元素不同
System.out.println(Arrays.equals(b, d));//false 数组长度不相等,元素相同
}
}
源码
public static boolean equals(int[] a, int[] a2) {
if (a==a2)
return true; //如果两个数组地址相等,也就是同一个数组,返回true
if (a==null || a2==null)
return false; //如果两个数组中只要有一个为null,返回false
int length = a.length; //保存数组a的长度
if (a2.length != length)
return false; //如果两个数组长度不同,返回flase
for (int i=0; i<length; i++)//for循环变量两个数组,如果两个数组对应位置元素不等,就返回false
if (a[i] != a2[i])
return false;
return true;
}
3、数组元素的比较
排序必须根据对象的实际类型执行比较操作。各种不同类型的对象排序就需要写不同的排序方法,这样很难实现代码重用而且找出代码冗余。排序算法是不变的,而比较的对象是变化的,那么我们就通过使用策略,对将会变化的代码封装在单独的类中(策略对象),再讲策略对象传递给总是相同的代码,这些代码将使用策略来完成算法。策略模式能对算法更好的封装。策略模式
java中提供了两种方式实现比较功能:一种是实现java.lang.Comparable接口,另一种是java.util.Comparator接口。
代码表示:
Comparable接口实现
int compareTo(T o) //o 要比较的对象。
说明:
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
对于所有x和y,实现者必须确保sgn(x.compareTo(y))== -sgn(y.compareTo(x)).
强烈建议,但并非严格要求(x.compareTo(y)== 0)==(x.equals(y))。 一般来说,任何实现Comparable接口并且违反此条件的类都应该清楚地表明这一事实。 注意:此类具有与equals不一致的自然顺序。
public class Student implements Comparable<Student> {
private int stuNum;
private String name;
public Student(int stuNum,String name) {
this.name=name;
this.stuNum = stuNum;
}
public int getStuNum() {
return stuNum;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "[学号:"+getStuNum()+" 姓名:"+getName()+"]";
}
@Override
public int compareTo(Student o) { //重写接口唯一的方法,自定义升序降序方式
return -(this.getStuNum()-o.getStuNum()); //学号降序
}
public static void main(String[] args) {
Student[] students = new Student[5];
students[0] = new Student(2,"tom");
students[1] = new Student(0,"alice");
students[2] = new Student(3,"mary");
students[3] = new Student(7,"mack");
students[4] = new Student(5,"apple");
System.out.println("排序前:"+Arrays.toString(students));
Arrays.sort(students);//根据学号降序排列
System.out.println("排序后:"+Arrays.toString(students));//
}
}
Comparator接口的实现
int compare(T o1,T o2) //o1、o2两个比较的对象
比较它的两个参数的顺序。 返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。
public class Student {
private int stuNum;
private String name;
public Student(int stuNum,String name) {
this.name=name;
this.stuNum = stuNum;
}
public int getStuNum() {
return stuNum;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "[学号:"+getStuNum()+" 姓名:"+getName()+"]";
}
public static void main(String[] args) {
Student[] students = new Student[5];
students[0] = new Student(2,"tom");
students[1] = new Student(0,"alice");
students[2] = new Student(3,"bary");
students[3] = new Student(7,"mack");
students[4] = new Student(5,"apple");
System.out.println("排序前:"+Arrays.toString(students));
Arrays.sort(students,new StuComparator());//根据姓名字典降序排列
System.out.println("排序后:"+Arrays.toString(students));//
}
}
class StuComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return -(o1.getName().compareTo(o2.getName()));//根据姓名字母字典降序排序
}
}
打印结果:
排序前:[[学号:2 姓名:tom], [学号:0 姓名:alice], [学号:3 姓名:bary], [学号:7 姓名:mack], [学号:5 姓名:apple]]
排序后:[[学号:2 姓名:tom], [学号:7 姓名:mack], [学号:3 姓名:bary], [学号:5 姓名:apple], [学号:0 姓名:alice]]
4、binarySearch()
使用二进制搜索算法在指定的int数组中搜索指定的值。在进行此调用之前,必须对数组进行排序(如sort(int [])方法)。如果未排序,则结果未定义。如果数组包含具有指定值的多个元素,则无法保证将找到哪个元素。
public class BinarySearchTest {
public static void main(String[] args) {
int[] a = { 2, 3, 1, 4, 5, 3, 8, 7, 9, 10, 21, 3, 4, 6, 4, 33 };
//Arrays.sort(a);
//System.out.println(Arrays.toString(a));
//int index = Arrays.binarySearch(a, 10);//-16,如果数组是没有排序的,则结果错的。
int index = Arrays.binarySearch(a, 10);
System.out.println(index);
}
}
排好序的结果:
[1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 7, 8, 9, 10, 21, 33]
13
5、toString()
返回指定数组内容的字符串表示形式。字符串表示由数组元素的列表组成,用方括号括起来(“[]”)。相邻元素由字符“,”(逗号后跟空格)分隔。
源码:
public static String toString(int[] a) { //重写后的toString方法
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);//将数组元素添加到字符串缓冲区
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}