詳解Java合并數(shù)組的兩種實現(xiàn)方式
最近在寫代碼時遇到了需要合并兩個數(shù)組的需求,突然發(fā)現(xiàn)以前沒用過,于是研究了一下合并數(shù)組的方式,總結如下。
1.System.arraycopy()方法
(1) 解析
通過閱讀JDK源碼,我可以知道方法原型如下:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
其中:
src是源數(shù)組
srcPos是源數(shù)組復制的起始位置
dest是目標數(shù)組
destPos是目標數(shù)組接收復制數(shù)據(jù)的起始位置
length是復制的長度(源數(shù)組中從復制起始位置srcPos開始需要復制的長度)
可以看到,該方法是本地方法,我們不能更深一步的了解其中的原理,但是我們可以知道其作用就是將源數(shù)組從起始位置srcPos開始將length長度的元素復制到目標數(shù)組,目標數(shù)組從destPos位置開始接收復制元素。
(2) 示例
String[] aa = {"11","22","33"}; String[] bb = {"44","55","66"}; String[] cc = {"77","88","99"}; // 合并兩個數(shù)組 String[] dd = new String[aa.length + bb.length]; System.arraycopy(aa, 0, dd, 0, aa.length); System.arraycopy(bb, 0, dd, aa.length, bb.length); // 合并三個數(shù)組 String[] ee = new String[aa.length + bb.length + cc.length]; System.arraycopy(aa, 0, ee, 0, aa.length); System.arraycopy(bb, 0, ee, aa.length, bb.length); System.arraycopy(cc, 0, ee, aa.length + bb.length, cc.length);
2.ArrayUtils.addAll()方法
(1) 解析
ArrayUtils工具類在apache commons-lang3-3.5中的commons-lang3-3.5.jar(jar包下載地址)中,所以使用之前需要導入這個包。通過閱讀其源碼,我們可以發(fā)現(xiàn),其實addAll()方法本質上還是調用System.arraycopy()方法。
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 // a處 T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length); System.arraycopy(array1, 0, joinedArray, 0, array1.length); try { // b處 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; }
這個方法關鍵的兩個部分就是代碼中標注的a、b兩處。a處首先通過反射的方式定義了一個長度為array1、array2長度之和的數(shù)組joinedArray,然后將array1拷貝到joinedArray,b處將array2拷貝到joinedArray中。除了這兩處,還有異常處理需要注意,在捕獲異常后,判斷了type1是不是繼承于type2,也就是判斷array1所對應的類型是否與array2對應類型相同,或者array1所對應的類型是否是array2對應類型的子類,否則將出現(xiàn)不兼容的情況。
(2) 示例
// 合并兩個數(shù)組 String[] ff = ArrayUtils.addAll(aa, bb); // 將多個字符串合并到數(shù)組構成新數(shù)組 String[] gg = ArrayUtils.addAll(aa, "12", "13"); String[] hh = ArrayUtils.addAll(aa, "12", "13", "14"); String[] ii = ArrayUtils.addAll(aa, "12", "13", "14", "15"); // 合并三個數(shù)組 String[] jj = ArrayUtils.addAll(aa, bb); String[] kk = ArrayUtils.addAll(jj, cc);
需要說明的是,addAll()的第二個參數(shù)是可變參數(shù),可以傳入多個相同類型的值,或者一個該類型的數(shù)組。
(3) 錯誤處理
我在使用過程中遇到一個問題,具體如下:
代碼1:
String[] ll = ArrayUtils.addAll(aa, bb, cc);
根據(jù)提示發(fā)現(xiàn),addAll()返回值類型是Serializable[],所有不能喝String[]兼容。于是我將代碼改成如下代碼:
代碼2:
ArrayUtils.addAll(aa, bb, cc);
我以為不接收返回值只是合并就不會報錯了,雖然通過了編譯,但是運行還是報錯了。錯誤信息如下:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot store java.io.Serializable in an array of java.lang.String at org.apache.commons.lang3.ArrayUtils.addAll(ArrayUtils.java:5084) at com.liu.date20170524.MergeArrays.main(MergeArrays.java:44) Caused by: java.lang.ArrayStoreException at java.lang.System.arraycopy(Native Method) at org.apache.commons.lang3.ArrayUtils.addAll(ArrayUtils.java:5073) ... 1 more
由于當時陷入了慣性思維,認為addAll和List等的addAll()方法類型,可以將多個列表(這里是數(shù)組)進行合并,所以一直沒想明白錯誤出在哪里。后來才發(fā)現(xiàn),addAll()的第二個參數(shù)的類型是T,不是T[],所以不能合并兩個以上的數(shù)組。望各位引以為戒。
參考:http://www.dbjr.com.cn/article/129962.htm
以上所述是小編給大家介紹的Java合并數(shù)組的兩種實現(xiàn)方式詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
相關文章
Java編程實現(xiàn)的二維數(shù)組轉置功能示例
這篇文章主要介紹了Java編程實現(xiàn)的二維數(shù)組轉置功能,結合實例形式分析了Java二維數(shù)組的遍歷、運算、賦值等實現(xiàn)轉置的相關操作技巧,需要的朋友可以參考下2018-01-01SpringBoot項目中配置application.yml中server.port不生效的問題
這篇文章主要介紹了SpringBoot項目中配置application.yml中server.port不生效的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12SpringBoot結合FreeMarker視圖渲染的實現(xiàn)
FreeMarker它允許開發(fā)人員使用模板和數(shù)據(jù)來生成輸出文本,如HTML網頁、電子郵件、配置文件和源代碼等,本文主要介紹了SpringBoot結合FreeMarker視圖渲染的實現(xiàn),感興趣的可以了解一下2024-03-03SpringCloud OpenFeign超詳細講解模板化遠程通信的實現(xiàn)
這篇文章主要介紹了SpringCloudSpringboot集成OpenFeign實現(xiàn)模板化遠程通信,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2022-07-07SpringBoot中yml多環(huán)境配置的3種方法
這篇文章主要給大家介紹了SpringBoot中yml多環(huán)境配置的3種方法,文中有詳細的代碼示例供大家參考,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2023-10-10