jdk源码阅读之Arrays

Arrays实现了数组常见的一些操作,比如:排序、数组拷贝等。

  • 排序sort

Arrays类为了通用性,对方法进行了大量的重载,在这里只讲通用的。

public static void sort(Object[] a) {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a);
        else
            ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
    }

进行排序的数组一定要实现Comparable接口,否则会报错,举个例子:

import java.util.Arrays;
class A  implements Comparable<A>  {
	private int i;
	public A(int i) {
		this.i = i;
	}
@Override
public int compareTo(A o) {
		int oi = o.i;
		return i > oi ? 1 : (i == oi ? 0 : -1);
	}
	public int getI() {
		return i;
	}
}
public class TestDemo1 implements Cloneable {
	public static void main(String[] args) throws Exception {
		A[] a = { new A(3), new A(8), new A(4), new A(6), new A(1), };
		Arrays.sort(a);
		for (A a2 : a) {
			System.out.print(a2.getI());
		}
	}
}

这样数组a可以正常排序,如果A类没有实现Comparable接口,在进行排序的时候会报 java.lang.ClassCastException异常。

  • 二分查找binarySearch

public static int binarySearch(Object[] a, Object key) {
        return binarySearch0(a, 0, a.length, key);
    }
 private static int binarySearch0(Object[] a, int fromIndex, int toIndex,
                                     Object key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            @SuppressWarnings("rawtypes")
            Comparable midVal = (Comparable)a[mid];
            @SuppressWarnings("unchecked")
            int cmp = midVal.compareTo(key);

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }

由代码可知,查找到的依据是两者的compareTo方法返回的是否是0,而不是调用equals方法,这一点要注意。

  • 数组相等equals

public static boolean equals(Object[] a, Object[] a2) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;

        int length = a.length;
        if (a2.length != length)
            return false;

        for (int i=0; i<length; i++) {
            Object o1 = a[i];
            Object o2 = a2[i];
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }

        return true;
    }

对比两个数组的每一个对象调用equals方法,如果每个对象调用equals都返回0,那么说明两个数组相等。

  • 填充数组fill

public static void fill(Object[] a, Object val) {
        for (int i = 0, len = a.length; i < len; i++)
            a[i] = val;
    }

fill方法用来将数组a的每一个元素都赋值为val,当val是引用的话,那么数组的每一个元素都是引用,并且引用的是同一个对象;当val为基本数据类型的话,数组的每一个元素的值为val。

  • 数组拷贝copyOf/copyOfRange

@SuppressWarnings("unchecked")
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
@SuppressWarnings("unchecked")
    public static <T> T[] copyOfRange(T[] original, int from, int to) {
        return copyOfRange(original, from, to, (Class<? extends T[]>) original.getClass());
    }

对于copyOf(T[] original, int newLength),当newLength大于origin数组的长度时,返回的数组大小为newLength,剩余的部分用0填充。
对于copyOfRange(T[] original, int from, int to),是部分拷贝。

  • 将参数转换成List

@SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

asList方法是一个带不定参数的方法,把这些参数转换成List。

猜你喜欢

转载自blog.csdn.net/whoami_I/article/details/86023594
今日推荐