文章目录
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(", ");
}
}