Arrays工具类部分常用方法 Java
程序员文章站
2024-03-06 21:25:20
...
Arrays工具类部分常用方法
版本:JDK 11
可以直接看API帮助文档,可以从这里下: https://pan.baidu.com/s/1zZNRNprhz0RxGd5xbYcyxA
提取码:y8e4
部分方法
方法 | 描述 |
---|---|
static List asList(T… a) | 返回由指定数组支持的固定大小的列表 |
static int binarySearch(int[] a, int key) | 使用二分搜索算法在指定的int数组中搜索指定的值 |
static int[] copyOf(int[] original, int newLength) | 从original中复制newLength个元素,newLength如果大于origianl则填充0, 小于则截断 |
static int[] copyOfRange(int[] original, int from, int to) | 将指定数组的指定范围复制到新数组中 |
static void fill (int[] a, int val) | 将指定的int值分配给指定的int数组的每个元素 |
static int mismatch (int[] a, int[] b) | 查找并返回两个int数组之间第一个不匹配的相对索引,否则如果未找到不匹配返回-1 |
static void sort(int[] a) | 将指定的数组升序排序 |
toString(int[] a) | 返回指定数组的字符串表示形式 |
static IntStream(int[] a) | 返回以指定数组作为源的顺序InputStream,流式编程的时候用 |
源码及测试
asList(T… a)
源码如下
/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param <T> the class of the objects in the array
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
测试如下:
直接放数组的话放的是地址
@Test
public void asListTest() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(list);
int[] arr = {2, 4, 6, 8, 10};
List<int[]> list2 = Arrays.asList(arr);
System.out.println(list2);
}
[1, 2, 3, 4, 5]
[[I@6121c9d6]
binarySearch (int[] a, int key)
源码:
/**
* Searches the specified array of ints for the specified value using the
* binary search algorithm. The array must be sorted (as
* by the {@link #sort(int[])} method) prior to making this call. If it
* is not sorted, the results are undefined. If the array contains
* multiple elements with the specified value, there is no guarantee which
* one will be found.
*
* @param a the array to be searched
* @param key the value to be searched for
* @return index of the search key, if it is contained in the array;
* otherwise, <code>(-(<i>insertion point</i>) - 1)</code>. The
* <i>insertion point</i> is defined as the point at which the
* key would be inserted into the array: the index of the first
* element greater than the key, or {@code a.length} if all
* elements in the array are less than the specified key. Note
* that this guarantees that the return value will be >= 0 if
* and only if the key is found.
*/
public static int binarySearch(int[] a, int key) {
return binarySearch0(a, 0, a.length, key);
}
// Like public version, but without range checks.
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.
}
测试:
@Test
public void binarySearchTest() {
int[] arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
System.out.println(Arrays.binarySearch(arr, 3));
System.out.println(Arrays.binarySearch(arr, 20));
}
3
-11
copyOf(int[] original, int newLength)
/**
* Copies the specified array, truncating or padding with zeros (if necessary)
* so the copy has the specified length. For all indices that are
* valid in both the original array and the copy, the two arrays will
* contain identical values. For any indices that are valid in the
* copy but not the original, the copy will contain {@code 0}.
* Such indices will exist if and only if the specified length
* is greater than that of the original array.
*
* @param original the array to be copied
* @param newLength the length of the copy to be returned
* @return a copy of the original array, truncated or padded with zeros
* to obtain the specified length
* @throws NegativeArraySizeException if {@code newLength} is negative
* @throws NullPointerException if {@code original} is null
* @since 1.6
*/
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;
}
arraycopy是个native方法,表示是用c/c++实现的
/**
* Copies an array from the specified source array, beginning at the
* specified position, to the specified position of the destination array.
* A subsequence of array components are copied from the source
* array referenced by {@code src} to the destination array
* referenced by {@code dest}. The number of components copied is
* equal to the {@code length} argument. The components at
* positions {@code srcPos} through
* {@code srcPos+length-1} in the source array are copied into
* positions {@code destPos} through
* {@code destPos+length-1}, respectively, of the destination
* array.
* <p>
* If the {@code src} and {@code dest} arguments refer to the
* same array object, then the copying is performed as if the
* components at positions {@code srcPos} through
* {@code srcPos+length-1} were first copied to a temporary
* array with {@code length} components and then the contents of
* the temporary array were copied into positions
* {@code destPos} through {@code destPos+length-1} of the
* destination array.
* <p>
* If {@code dest} is {@code null}, then a
* {@code NullPointerException} is thrown.
* <p>
* If {@code src} is {@code null}, then a
* {@code NullPointerException} is thrown and the destination
* array is not modified.
* <p>
* Otherwise, if any of the following is true, an
* {@code ArrayStoreException} is thrown and the destination is
* not modified:
* <ul>
* <li>The {@code src} argument refers to an object that is not an
* array.
* <li>The {@code dest} argument refers to an object that is not an
* array.
* <li>The {@code src} argument and {@code dest} argument refer
* to arrays whose component types are different primitive types.
* <li>The {@code src} argument refers to an array with a primitive
* component type and the {@code dest} argument refers to an array
* with a reference component type.
* <li>The {@code src} argument refers to an array with a reference
* component type and the {@code dest} argument refers to an array
* with a primitive component type.
* </ul>
* <p>
* Otherwise, if any of the following is true, an
* {@code IndexOutOfBoundsException} is
* thrown and the destination is not modified:
* <ul>
* <li>The {@code srcPos} argument is negative.
* <li>The {@code destPos} argument is negative.
* <li>The {@code length} argument is negative.
* <li>{@code srcPos+length} is greater than
* {@code src.length}, the length of the source array.
* <li>{@code destPos+length} is greater than
* {@code dest.length}, the length of the destination array.
* </ul>
* <p>
* Otherwise, if any actual component of the source array from
* position {@code srcPos} through
* {@code srcPos+length-1} cannot be converted to the component
* type of the destination array by assignment conversion, an
* {@code ArrayStoreException} is thrown. In this case, let
* <b><i>k</i></b> be the smallest nonnegative integer less than
* length such that {@code src[srcPos+}<i>k</i>{@code ]}
* cannot be converted to the component type of the destination
* array; when the exception is thrown, source array components from
* positions {@code srcPos} through
* {@code srcPos+}<i>k</i>{@code -1}
* will already have been copied to destination array positions
* {@code destPos} through
* {@code destPos+}<i>k</I>{@code -1} and no other
* positions of the destination array will have been modified.
* (Because of the restrictions already itemized, this
* paragraph effectively applies only to the situation where both
* arrays have component types that are reference types.)
*
* @param src the source array.
* @param srcPos starting position in the source array.
* @param dest the destination array.
* @param destPos starting position in the destination data.
* @param length the number of array elements to be copied.
* @throws IndexOutOfBoundsException if copying would cause
* access of data outside array bounds.
* @throws ArrayStoreException if an element in the {@code src}
* array could not be stored into the {@code dest} array
* because of a type mismatch.
* @throws NullPointerException if either {@code src} or
* {@code dest} is {@code null}.
*/
@HotSpotIntrinsicCandidate
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
测试
@Test
public void copyOfTest() {
int[] arr = {2, 4, 6, 8, 10};
int[] newArr = Arrays.copyOf(arr, 3);
System.out.println(Arrays.toString(newArr));
int[] newArr2 = Arrays.copyOf(arr, 10);
System.out.println(Arrays.toString(newArr2));
}
[2, 4, 6]
[2, 4, 6, 8, 10, 0, 0, 0, 0, 0]
copyOfRange(int[] original, int from, int to)
源码:
/**
* Copies the specified range of the specified array into a new array.
* The initial index of the range ({@code from}) must lie between zero
* and {@code original.length}, inclusive. The value at
* {@code original[from]} is placed into the initial element of the copy
* (unless {@code from == original.length} or {@code from == to}).
* Values from subsequent elements in the original array are placed into
* subsequent elements in the copy. The final index of the range
* ({@code to}), which must be greater than or equal to {@code from},
* may be greater than {@code original.length}, in which case
* {@code 0} is placed in all elements of the copy whose index is
* greater than or equal to {@code original.length - from}. The length
* of the returned array will be {@code to - from}.
*
* @param original the array from which a range is to be copied
* @param from the initial index of the range to be copied, inclusive
* @param to the final index of the range to be copied, exclusive.
* (This index may lie outside the array.)
* @return a new array containing the specified range from the original array,
* truncated or padded with zeros to obtain the required length
* @throws ArrayIndexOutOfBoundsException if {@code from < 0}
* or {@code from > original.length}
* @throws IllegalArgumentException if {@code from > to}
* @throws NullPointerException if {@code original} is null
* @since 1.6
*/
public static int[] copyOfRange(int[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
int[] copy = new int[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
测试:
@Test
public void copyOfRangeTest() {
int[] arr = {2, 4, 6, 8, 10};
int[] copy1 = Arrays.copyOfRange(arr, 1, 3);
System.out.println(Arrays.toString(copy1));
//int[] copy2 = Arrays.copyOfRange(arr, -2, 2);
//System.out.println(Arrays.toString(copy2));
//java.lang.ArrayIndexOutOfBoundsException: arraycopy: source index -2 out of bounds for int[5]
int[] copy3 = Arrays.copyOfRange(arr, 3, 10);
System.out.println(Arrays.toString(copy3));
}
[4, 6]
[8, 10, 0, 0, 0, 0, 0]
fill (int[] a, int val)
源码:
/**
* Assigns the specified int value to each element of the specified array
* of ints.
*
* @param a the array to be filled
* @param val the value to be stored in all elements of the array
*/
public static void fill(int[] a, int val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
测试:
@Test
public void fillTest() {
int[] arr = new int[5];
Arrays.fill(arr, -1);
System.out.println(Arrays.toString(arr));
}
[-1, -1, -1, -1, -1]
mismatch(int[] a, int[] b)
源码
/**
* Finds and returns the index of the first mismatch between two {@code int}
* arrays, otherwise return -1 if no mismatch is found. The index will be
* in the range of 0 (inclusive) up to the length (inclusive) of the smaller
* array.
*
* <p>If the two arrays share a common prefix then the returned index is the
* length of the common prefix and it follows that there is a mismatch
* between the two elements at that index within the respective arrays.
* If one array is a proper prefix of the other then the returned index is
* the length of the smaller array and it follows that the index is only
* valid for the larger array.
* Otherwise, there is no mismatch.
*
* <p>Two non-{@code null} arrays, {@code a} and {@code b}, share a common
* prefix of length {@code pl} if the following expression is true:
* <pre>{@code
* pl >= 0 &&
* pl < Math.min(a.length, b.length) &&
* Arrays.equals(a, 0, pl, b, 0, pl) &&
* a[pl] != b[pl]
* }</pre>
* Note that a common prefix length of {@code 0} indicates that the first
* elements from each array mismatch.
*
* <p>Two non-{@code null} arrays, {@code a} and {@code b}, share a proper
* prefix if the following expression is true:
* <pre>{@code
* a.length != b.length &&
* Arrays.equals(a, 0, Math.min(a.length, b.length),
* b, 0, Math.min(a.length, b.length))
* }</pre>
*
* @param a the first array to be tested for a mismatch
* @param b the second array to be tested for a mismatch
* @return the index of the first mismatch between the two arrays,
* otherwise {@code -1}.
* @throws NullPointerException
* if either array is {@code null}
* @since 9
*/
public static int mismatch(int[] a, int[] b) {
int length = Math.min(a.length, b.length); // Check null array refs
if (a == b)
return -1;
int i = ArraysSupport.mismatch(a, b, length);
return (i < 0 && a.length != b.length) ? length : i;
}
测试:
@Test
public void mismatchTest() {
int[] arr = {1, 2, 3};
int[] arr2 = {1, 2, 4};
System.out.println(Arrays.mismatch(arr, arr2));
}
2
sort(int[] a)
源码:
/**
* Sorts the specified array into ascending numerical order.
*
* <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
* by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This 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.
*
* @param a the array to be sorted
*/
public static void sort(int[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
/**
* Sorts the specified range of the array using the given
* workspace array slice if possible for merging
*
* @param a the array to be sorted
* @param left the index of the first element, inclusive, to be sorted
* @param right the index of the last element, inclusive, to be sorted
* @param work a workspace array (slice)
* @param workBase origin of usable space in work array
* @param workLen usable size of work array
*/
static void sort(int[] a, int left, int right,
int[] work, int workBase, int workLen) {
// Use Quicksort on small arrays
if (right - left < QUICKSORT_THRESHOLD) {
sort(a, left, right, true);
return;
}
/*
* Index run[i] is the start of i-th run
* (ascending or descending sequence).
*/
int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left;
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
// Equal items in the beginning of the sequence
while (k < right && a[k] == a[k + 1])
k++;
if (k == right) break; // Sequence finishes with equal items
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
// Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
}
// Merge a transformed descending sequence followed by an
// ascending sequence
if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
count--;
}
/*
* The array is not highly structured,
* use Quicksort instead of merge sort.
*/
if (++count == MAX_RUN_COUNT) {
sort(a, left, right, true);
return;
}
}
// These invariants should hold true:
// run[0] = 0
// run[<last>] = right + 1; (terminator)
if (count == 0) {
// A single equal run
return;
} else if (count == 1 && run[count] > right) {
// Either a single ascending or a transformed descending run.
// Always check that a final run is a proper terminator, otherwise
// we have an unterminated trailing run, to handle downstream.
return;
}
right++;
if (run[count] < right) {
// Corner case: the final run is not a terminator. This may happen
// if a final run is an equals run, or there is a single-element run
// at the end. Fix up by adding a proper terminator at the end.
// Note that we terminate with (right + 1), incremented earlier.
run[++count] = right;
}
// Determine alternation base for merge
byte odd = 0;
for (int n = 1; (n <<= 1) < count; odd ^= 1);
// Use or create temporary array b for merging
int[] b; // temp array; alternates with a
int ao, bo; // array offsets from 'left'
int blen = right - left; // space needed for b
if (work == null || workLen < blen || workBase + blen > work.length) {
work = new int[blen];
workBase = 0;
}
if (odd == 0) {
System.arraycopy(a, left, work, workBase, blen);
b = a;
bo = 0;
a = work;
ao = workBase - left;
} else {
b = work;
ao = 0;
bo = workBase - left;
}
// Merging
for (int last; count > 1; count = last) {
for (int k = (last = 0) + 2; k <= count; k += 2) {
int hi = run[k], mi = run[k - 1];
for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {
b[i + bo] = a[p++ + ao];
} else {
b[i + bo] = a[q++ + ao];
}
}
run[++last] = hi;
}
if ((count & 1) != 0) {
for (int i = right, lo = run[count - 1]; --i >= lo;
b[i + bo] = a[i + ao]
);
run[++last] = right;
}
int[] t = a; a = b; b = t;
int o = ao; ao = bo; bo = o;
}
}
测试:
@Test
public void sortTest() {
int[] arr = {5, 3, 9, 2, 4};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
[2, 3, 4, 5, 9]
toString(int[] a)
源码:
/**
* Returns a string representation of the contents of the specified array.
* The string representation consists of a list of the array's elements,
* enclosed in square brackets ({@code "[]"}). Adjacent elements are
* separated by the characters {@code ", "} (a comma followed by a
* space). Elements are converted to strings as by
* {@code String.valueOf(int)}. Returns {@code "null"} if {@code a} is
* {@code null}.
*
* @param a the array whose string representation to return
* @return a string representation of {@code a}
* @since 1.5
*/
public static String toString(int[] 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(", ");
}
}
测试:
@Test
public void toStringTest() {
int[] arr = {3, 4, 54, 3, 12};
System.out.println(Arrays.toString(arr));
}
[3, 4, 54, 3, 12]
stream(int[] a)
测试:
@Test
public void streamTest() {
int[] arr = {1,4,5,2,3,6,4,};
IntStream stream = Arrays.stream(arr);
System.out.println(stream);
}
java.util.stream.IntPipeline$Head@eafc191