Java中的數組合並,常見有五種實現方式:
- 使用JDK自帶的System.arraycopy()方法。
- 使用apache的commons-lang3包下的ArrayUtils.addAll(a,b)方法。
- 手把手帶你寫自己的array_utils.arraymergn()方法
3.1 最基礎的,新建一個新的數組,將需要合併的數組值添加進去。固定長度
3.2 多參實現多數組合並
3.3 泛型實現數組合並(重點)
下面對每個方法,進行詳細的介紹。不會按照順序,依照難易程度介紹:
方法1 2 3 循序漸進,時間緊的直接看 方法 4 5
1、JDK自帶的方法。
/*
* Copies an array from the specified source array, beginning at the
* specified position, to the specified position of the destination array.
* @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.
* @exception IndexOutOfBoundsException if copying would cause
* access of data outside array bounds.
* @exception ArrayStoreException if an element in the <code>src</code>
* array could not be stored into the <code>dest</code> array
* because of a type mismatch.
* @exception NullPointerException if either <code>src</code> or
* <code>dest</code> is <code>null</code>.
*/
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
看完源碼就是將源數組(src)從起始位置(srcPos)開始將長度(length)的元素複製到目標數組(dest),目標數組從指定位置(destPos)位置開始接收復制元素。
System.arraycopy()實現,該方法被 native修飾,無法看到底層,但是可以分析其實就是我們最常用的新建目標數組往裏面塞東西。
2、個人覺得最簡單也是最常用的方法。雖然low點
public int[] AddArray1(int[] a, int[] b, int[] c, int[] d) {
int[] Result = new int[a.length + b.length + c.length + d.length];
for (int i = 0; i < a.length; i++) {
Result[i] = a[i];
}
for (int i = 0; i < b.length; i++) {
Result[i + a.length] = b[i];
}
for (int i = 0; i < c.length; i++) {
Result[i + a.length + b.length] = c[i];
}
for (int i = 0; i < d.length; i++) {
Result[i + a.length + b.length + c.length] = d[i];
}
return Result;
}
@Test
public void test() {
int[] a = {1, 2, 3};
int[] b = {4, 5, 6};
int[] c = {7, 8, 9};
int[] d = {10, 11, 12};
int[] Result1;
Result1 = AddArray1(a, b, c, d);
for (int i : Result1) {
System.out.print(i + " ");
}
System.out.println("----------");
}
爲了舉個列子,寫了一堆重複代碼,依次for循環,Result接受其實就是JDK中的destPost的位置。
@Test 作者建的是Maven工程,單元測試框架,寫一個main,必須用static聲明,方法都得是static,顯得超級low。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency>
3、在方法2的步驟上,考慮到如果數組的個數不確定怎麼辦。
使用 ... JDK8帶的多參數判斷,很多人喜歡用Java的反射機制來獲取類中方法名中的參數。
我覺得還是使用JavaScript操作方法參數的方式,簡單 通俗
public int[] AddArray2(int[]... categorys) {
int size = categorys.length; //獲取參數個數
int length = 0;
for (int i = 0; i < size; i++) {
length += categorys[i].length; //每個數組的長度
}
int index = 0;
int[] Result = new int[length];
for (int i = 0; i < size; i++) {
for (int j = 0; j < categorys[i].length; j++) {
Result[index] = categorys[i][j];
index++;
}
}
return Result;
}
上面3個方法,學過Java的都會,我其實也不好意思寫出來,但是沒辦法,照顧新人,有教無類。
4、使用Apache的common-lang3.jar包,隨便大家下載jar還是添加maven依賴,這不是重點
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency>
使用ArrayUtils.addAll(a,b); a b 數據類型必須一致
分析源碼:
源碼有點長,
1、官方提供的幾種方法。
ArrayUtils.addAll(null, null) = null
* ArrayUtils.addAll(array1, null) = cloned copy of array1
* ArrayUtils.addAll(null, array2) = cloned copy of array2
* ArrayUtils.addAll([], []) = []
* ArrayUtils.addAll([null], [null]) = [null, null]
* ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]。
2、當數組中有null的時候,使用淺克隆。(深淺克隆,可以參考後期推出的設計模塊)
利用Java反射機制獲取參數類型和參數數量,和泛型參數。
最後還是使用arraycopy的方法。
3、其實多參數方法3中已經介紹了,泛型實現在方法5中具體介紹。
/**
* <p>Adds all the elements of the given arrays into a new array.
* <p>The new array contains all of the element of {@code array1} followed
* by all of the elements {@code array2}. When an array is returned, it is always
* a new array.
*
* <pre>
* ArrayUtils.addAll(null, null) = null
* ArrayUtils.addAll(array1, null) = cloned copy of array1
* ArrayUtils.addAll(null, array2) = cloned copy of array2
* ArrayUtils.addAll([], []) = []
* ArrayUtils.addAll([null], [null]) = [null, null]
* ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
* </pre>
*
* @param <T> the component type of the array
* @param array1 the first array whose elements are added to the new array, may be {@code null}
* @param array2 the second array whose elements are added to the new array, may be {@code null}
* @return The new array, {@code null} if both arrays are {@code null}.
* The type of the new array is the type of the first array,
* unless the first array is null, in which case the type is the same as the second array.
* @since 2.1
* @throws IllegalArgumentException if the array types are incompatible
*/
public static <T> T[] addAll(final T[] array1, final T... array2) {
if (array1 == null) {
return clone(array2);
} else if (array2 == null) {
return clone(array1);
}
final Class<?> type1 = array1.getClass().getComponentType();
@SuppressWarnings("unchecked") // OK, because array is of type T
final
T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
try {
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
} catch (final ArrayStoreException ase) {
// Check if problem was due to incompatible types
/*
* We do this here, rather than before the copy because:
* - it would be a wasted check most of the time
* - safer, in case check turns out to be too strict
*/
final Class<?> type2 = array2.getClass().getComponentType();
if (!type1.isAssignableFrom(type2)) {
throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of "
+ type1.getName(), ase);
}
throw ase; // No, so rethrow original
}
return joinedArray;
}
官方提供的實現方法:快速重載
方法5:獲取泛型數組
上面的Java中方法多參數操作,已經懵了,泛型會更懵了,學習Java的實現,很多老師都會手把手實現List,Map,其中就是用到了泛型,接下里介紹,利用泛型實現自定義類型(數組)。
1、首先定義接口
public interface GeneratorT<T> {
public T getAll();
}
對就是這麼簡單,然後實現接口就完事了
2、接口實現
class DcT implements GeneratorT {
private Object[] array;
public DcT(int size) {
array = new Object[size];
}
public void put(int index, Object item) {
array[index] = item;
}
@Override
public Object[] getAll() {
return array;
}
}
Dc就是作者的名字了,T表示泛型,類名DcT沒什麼含義,該類主要的功能的是:
構造器輸入數組的大小,put(index,item);往數組index的位置放入item。
@override getAll() 就是獲取數組值。
3、測試
double[] a1 = {1.0, 2.0, 3.0};
double[] a2 = {4.0, 5.0, 6.0};
DcT t = new DcT(a1.length);
for (int i = 0; i < a1.length; i++) {
t.put(i, a1[i]);
}
Object[] all = t.getAll();
for (int i = 0; i <all.length ; i++) {
System.out.println(all[i]); //輸出結果
}
方法5已經獲取了單個數組的值(隨你什麼類型的數組),接下來就是數組的合併了(上面介紹了4種方法),方法5實現了不同類型的數組只需要一個函數就可以進行合併。
將輸入類型提升到了Object好處是接受多種類型,壞處是可以進行不同類型數組的合併,將方法3改成泛型的形式,實現不同類型數組的合併(並沒有實際的意思純粹是爲了好玩,代碼就不貼了,沒有實際意義)。方法是將變量值全部變成了String。
不足之處,請在下面留言。謝謝大家堅持到現在,作爲程序猿的不易。