从源码分析Arrays类的常用方法

x33g5p2x  于2021-12-31 转载在 其他  
字(7.2k)|赞(0)|评价(0)|浏览(414)

Arrays类概述

Arrays类在源码中的声明:

/** * This class contains various methods for manipulating arrays (such as * sorting and searching). This class also contains a static factory * that allows arrays to be viewed as lists. * * <p>The methods in this class all throw a {@code NullPointerException}, * if the specified array reference is null, except where noted. * * <p>The documentation for the methods contained in this class includes * briefs description of the <i>implementations</i>. Such descriptions should * be regarded as <i>implementation notes</i>, rather than parts of the * <i>specification</i>. Implementors should feel free to substitute other * algorithms, so long as the specification itself is adhered to. (For * example, the algorithm used by {@code sort(Object[])} does not have to be * a MergeSort, but it does have to be <i>stable</i>.) * * <p>This class is a member of the * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. */
public class Arrays

Arrays类可以看做是一个数组工具类,它包含了用于操作数组的各种方法(如排序和搜索)。 该类还包含一个静态工厂,可以将数组视为列表。

如果指定的数组引用为空,则该类中的方法都抛出一个NullPointerException ,除非另有说明。

常用方法

Arrays类中的排序调用DualPivotQuicksort类中的排序方法实现。

关于DualPivotQuicksort类的声明如下:

/** * This class implements the Dual-Pivot Quicksort algorithm by * Vladimir Yaroslavskiy, Jon Bentley, and Josh Bloch. The algorithm * offers O(n log(n)) performance on many data sets that cause other * quicksorts to degrade to quadratic performance, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * All exposed methods are package-private, designed to be invoked * from public methods (in class Arrays) after performing any * necessary array bounds checks and expanding parameters into the * required forms. */
final class DualPivotQuicksort

DualPivotQuicksort被称为双轴快速排序,它汇集了多种排序算法,包括 优化后的归并排序(Timsort)、插入排序,成对插入排序、单轴快速排序,双轴快速排序
、计数排序。

DualPivotQuicksort源码见:DualPivotQuicksort源码

排序sort

它提供了对int、long、short、char、byte、float、double、object型数组的排序方法。

//按照数字顺序排列指定的数组。
    public static void sort(int[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

    //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
    public static void sort(int[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
    }

    //按照数字顺序排列指定的数组。
    public static void sort(long[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

    //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
    public static void sort(long[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
    }

    //按照数字顺序排列指定的数组。
    public static void sort(short[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

    //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
    public static void sort(short[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
    }

    //按照数字顺序排列指定的数组。
    public static void sort(char[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

    //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
    public static void sort(char[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
    }

    //按照数字顺序排列指定的数组。
    public static void sort(byte[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1);
    }

    //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
    public static void sort(byte[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
    }

    //按照数字顺序排列指定的数组。
    public static void sort(float[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

    //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
    public static void sort(float[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
    }

    //按照数字顺序排列指定的数组。
    public static void sort(double[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

    //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
    public static void sort(double[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
    }

除此之外,Arrays中还提供了许多其他类型的排序方法,如并行排序、归并排序等,这里不再一一例举。

搜索binarySearch

Arrays提供binarySearch二分查找方法,binarySearch()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的查找需要。

// 使用二叉搜索算法搜索指定的int数组的指定值。 在进行此调用之前,必须对数组进行排序(如sort(int[])方法)。 如果没有排序,结果是未定义的。
    public static int binarySearch(int[] a, int key) {
        return binarySearch0(a, 0, a.length, key);
    }

    //使用二叉搜索算法在指定数组的指定范围内搜索指定值。 
    public static int binarySearch(int[] a, int fromIndex, int toIndex,
                                   int key) {
        rangeCheck(a.length, fromIndex, toIndex);
        return binarySearch0(a, fromIndex, toIndex, key);
    }
    
    private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                     int key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            int midVal = a[mid];

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

这里只例举了int型数组的搜索,其他类型的数组搜索比较类似。

比较equals

Arrays中也提供了equals方法,比较两者是否相等。

equals()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

public static boolean equals(int[] a, int[] 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++)
            if (a[i] != a2[i])
                return false;

        return true;
    }

填充fill

Arrays中还提供了fill方法,用于将指定值填充在指定数组的每个元素(或指定范围的所有元素)。

fill()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

//将指定的int值分配给指定的int数组的每个元素。 
    public static void fill(int[] a, int val) {
        for (int i = 0, len = a.length; i < len; i++)
            a[i] = val;
    }

    // 将指定的int值分配给指定的int数组的指定范围的每个元素。 要填充的范围从索引fromIndex扩展到索引toIndex。 (如果fromIndex==toIndex ,要填充的范围是空的。) 
    public static void fill(int[] a, int fromIndex, int toIndex, int val) {
        rangeCheck(a.length, fromIndex, toIndex);
        for (int i = fromIndex; i < toIndex; i++)
            a[i] = val;
    }

赋值copyOf

copyOf方法用于复制指定数组,得到原始数组的副本,截断或填充空值以获取指定的长度 。

copyOf()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

将数组转换成列表asList

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

获取哈希码hashCode

hashCode用于根据指定数组的内容返回哈希码。

hashCode()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

public static int hashCode(long a[]) {
        if (a == null)
            return 0;

        int result = 1;
        for (long element : a) {
            int elementHash = (int)(element ^ (element >>> 32));
            result = 31 * result + elementHash;
        }

        return result;
    }

toString

返回指定数组的内容的字符串表示形式。 字符串表示由数组元素的列表组成,括在方括号( “[]” )中。 相邻的元素由字符", "分隔(逗号后跟一个空格)。

toString()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

public static String toString(long[] a) {
        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(", ");
        }
    }

相关文章