java 数组合并_拼接_详解Java合并数组的两种实现方式

详解Java合并数组的两种实现方式

发布于 2020-7-27|

复制链接

摘记: 最近在写代码时遇到了需要合并两个数组的需求,突然发现以前没用过,于是研究了一下合并数组的方式,总结如下。1.System.arraycopy()方法(1) 解析通过阅读JDK源码,我可以知道方法原型如下:

```java

public static native void arraycopy(Obje ..

最近在写代码时遇到了需要合并两个数组的需求,突然发现以前没用过,于是研究了一下合并数组的方式,总结如下。1.System.arraycopy()方法(1) 解析通过阅读JDK源码,我可以知道方法原型如下:

```java

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

```

其中:

src是源数组

srcPos是源数组复制的起始位置

dest是目标数组

destPos是目标数组接收复制数据的起始位置

length是复制的长度(源数组中从复制起始位置srcPos开始需要复制的长度)可以看到,该方法是本地方法,我们不能更深一步的了解其中的原理,但是我们可以知道其作用就是将源数组从起始位置srcPos开始将length长度的元素复制到目标数组,目标数组从destPos位置开始接收复制元素。(2) 示例

```java

String[] aa = {"11","22","33"};

String[] bb = {"44","55","66"};

String[] cc = {"77","88","99"};

// 合并两个数组

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);

// 合并三个数组

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包下载地址)中,所以使用之前需要导入这个包。通过阅读其源码,我们可以发现,其实addAll()方法本质上还是调用System.arraycopy()方法。

```java

public static 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长度之和的数组joinedArray,然后将array1拷贝到joinedArray,b处将array2拷贝到joinedArray中。除了这两处,还有异常处理需要注意,在捕获异常后,判断了type1是不是继承于type2,也就是判断array1所对应的类型是否与array2对应类型相同,或者array1所对应的类型是否是array2对应类型的子类,否则将出现不兼容的情况。(2) 示例

```java

// 合并两个数组

String[] ff = ArrayUtils.addAll(aa, bb);

// 将多个字符串合并到数组构成新数组

String[] gg = ArrayUtils.addAll(aa, "12", "13");

String[] hh = ArrayUtils.addAll(aa, "12", "13", "14");

String[] ii = ArrayUtils.addAll(aa, "12", "13", "14", "15");

// 合并三个数组

String[] jj = ArrayUtils.addAll(aa, bb);

String[] kk = ArrayUtils.addAll(jj, cc);

```

需要说明的是,addAll()的第二个参数是可变参数,可以传入多个相同类型的值,或者一个该类型的数组。(3) 错误处理我在使用过程中遇到一个问题,具体如下:

代码1:

```java

String[] ll = ArrayUtils.addAll(aa, bb, cc);

```

根据提示发现,addAll()返回值类型是Serializable[],所有不能喝String[]兼容。于是我将代码改成如下代码:

代码2:

```java

ArrayUtils.addAll(aa, bb, cc);

```

我以为不接收返回值只是合并就不会报错了,虽然通过了编译,但是运行还是报错了。错误信息如下:

```java

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

```

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值