java数组与java.util.Arrays工具类

概念

Java中数组属于引用类型。数组使用场合较多,对于数组的操作具有一定重复性,例如:数组拷贝,转换字符串,转换成数组,排序等等。
既然重复的操作与需求多,那么对于数组操作的支持就成了JDK中的一大需求。java.util.Arrays中提供了很多对数组操作的支持。

 

System.arraycopy: 数组元素拷贝

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

作用是从src数组的srcPos位置往dest数组的destPos位置拷贝length个元素。
当然,数组拷贝位置或元素数量不当时,可能出现ArrayIndexOutOfBoundException异常;类型不匹配时,会出现ArrayStoreException。

int[] a = new int[10];
int[] b = {1,2,3,4,5};

System.out.println("copy all elements of b[5] to a[10]:");
System.arraycopy(b, 0, a, 0, b.length);
System.out.println(Arrays.toString(a));

System.out.println("copy 4 elements of a[10] from index 0 to index 4:");
System.arraycopy(a, 0, a, 4, 4);
System.out.println(Arrays.toString(a));

System.out.println("copy 3 elements of a[10] from index 0 to index 8:");
System.arraycopy(a, 0, a, 8, 3);
System.out.println(Arrays.toString(a));

运行结果:

copy all elements of b[5] to a[10]:
[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
copy 4 elements of a[10] from index 0 to index 4:
[1, 2, 3, 4, 1, 2, 3, 4, 0, 0]
copy 3 elements of a[10] from index 0 to index 8:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException

 

Arrays.equals: 判断数组内容相等

Arrays中针对不同类型的数组提供了多个重载版本,
包括各种基本类型的比较:

public static boolean equals(int[] a, int[] a2);
public static boolean equals(long[] a, long[] a2);
public static boolean equals(boolean[] a, boolean[] a2);
......
以及对象数组之间的比较:
public static boolean equals(Object[] a, Object[] a2);

示例如下:

int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5};
System.out.println("int array compare equal? " + Arrays.equals(a, b));

Integer c[] = {new Integer(1), new Integer(3)};
Integer d[] = {new Integer(1), new Integer(3)};
System.out.println("Integer array compare equal? " + Arrays.equals(c,d));

Integer e[] = {1, 3}; //auto boxing
Integer f[] = {new Integer(1), new Integer(3)};
System.out.println("Integer array of autoBoxing and common Integer array: " + Arrays.equals(e,f));

//    int g[] = {1, 3};
//    Integer h[] = {new Integer(1), new Integer(3)};
//    System.out.println(Arrays.equals(h,g)); //compile error

运行结果:

int array compare equal? true
Integer array compare equal? true
Integer array of autoBoxing and common Integer array: true
对于最后一个int[]与Integer[]之间的比较,由于jdk中不存在不同类型之间比较的equal方法重载版本,且此处无法自动将int[]转换为封装类型的数组Integer[],因此结果是编译出错。

 

Arrays.fill: 数组填充内容,Arrays.toString转换字符串

public static void fill(Object[] a, Object val);

此方法将val填充至数组a中的每一个位置。需要注意的是,此处赋值是浅拷贝。
示例如下:

String strings[] = new String[10];
Arrays.fill(strings, "A");
System.out.println(Arrays.toString(strings));

结果如下:

[A, A, A, A, A, A, A, A, A, A]

 

Arrays.asList:将数组转换为List

public static <T> List<T> asList(T... a);

例如:

String strings[] = new String[10];
Arrays.fill(strings, "A");
List<String> asList = Arrays.asList(strings);
System.out.println(asList);

此方法使用泛型作为参数及返回值,因此当方法参数和返回值List参数类型不一致时,编译器会报错,例如:

int integers[] = {1,2};
// List<Integer> integers1 = Arrays.asList(integers); // compile error

将int[]转换为List<Integer>就会出现编译器报错。

 

Arrays.sort: 数组排序

sort对于不同类型提供了多个重载版本,例如int[]的排序方法重载版本,排序完成应该是从小至大的顺序:

public static void sort(int[] a);

示例如下:

int[] a = {2,3,1,5,4};
Arrays.sort(a);
System.out.println(Arrays.toString(a));

结果如下:

[1, 2, 3, 4, 5]

下面,针对对象进行排序测试。
对象进行比较的前提是,这种类型'可比较'。那么,它需要实现Comparable<T>接口。

class Person implements Comparable<Person>
{
	public Person(int age, String name) {
		this.age = age;
		this.name = name;
	}

	int age;
	String name;

	@Override
	public String toString() {
		return "Person{" +
				"age=" + age +
				", name='" + name + '\'' +
				'}';
	}

	@Override
	public int compareTo(Person o) {
		return (age-o.age);
	}
}	

下面构造测试:

Person jack = new Person(21,"jack");
Person rose = new Person(23,"rose");
Person judy = new Person(22,"judy");
Person joo = new Person(24,"joo");
Person persons[] = {jack, rose, judy, joo};
System.out.println(Arrays.toString(persons));

结果如下:

[Person{age=21, name='jack'}, Person{age=23, name='rose'}, Person{age=22, name='judy'}, Person{age=24, name='joo'}]

进行排序:

System.out.println("common sort:");
Arrays.sort(persons);
System.out.println(Arrays.toString(persons));

运行结果:

common sort:
[Person{age=21, name='jack'}, Person{age=22, name='judy'}, Person{age=23, name='rose'}, Person{age=24, name='joo'}]

或者,实现倒序:

System.out.println("reverse sort:");
Arrays.sort(persons, Collections.reverseOrder());
System.out.println(Arrays.toString(persons));

运行结果:

reverse sort:
[Person{age=24, name='joo'}, Person{age=23, name='rose'}, Person{age=22, name='judy'}, Person{age=21, name='jack'}

 

基于策略模式的自定义Comparator排序

然而,不同人对于相同的对象可能有不同的排序规则。例如,小李想让Person[]按年龄排序,小明想按照Person的名字排序...
基于策略模式,sort的重载版本可指定Comparator<T>作为排序算法:

public static <T> void sort(T[] a, Comparator<? super T> c);

先实现一个对于Person泛型的Comparator类,基于name排序:

class MyComparator implements Comparator<Person>
{
	@Override
	public int compare(Person o1, Person o2) {
		return o1.name.compareTo(o2.name);
	}
}

构造测试:

System.out.println("MyComparator:");
Arrays.sort(persons, new MyComparator());
System.out.println(Arrays.toString(persons));

运行结果:

MyComparator:
[Person{age=21, name='jack'}, Person{age=24, name='joo'}, Person{age=22, name='judy'}, Person{age=23, name='rose'}]

 

posted @ 2019-01-20 20:21  Xinxin_Brian  阅读(457)  评论(0编辑  收藏  举报