数组合并方式

在 Java 中,数组合并的方式有多种,具体取决于数组类型(基本类型数组或对象数组)、JDK 版本(是否支持 Stream API)以及是否需要修改原数组。以下是常见的实现方式:

一、基本类型数组(如 int[])合并

1. 使用 System.arraycopy()

这是最基础的方法,通过手动创建新数组并复制元素实现。

int[] arr1 = {1, 2, 3};
int[] arr2 = {4, 5, 6};

// 创建新数组,长度为两个原数组之和
int[] merged = new int[arr1.length + arr2.length];

// 复制第一个数组到新数组的前半部分
System.arraycopy(arr1, 0, merged, 0, arr1.length);
// 复制第二个数组到新数组的后半部分
System.arraycopy(arr2, 0, merged, arr1.length, arr2.length);

// 输出:[1, 2, 3, 4, 5, 6]
System.out.println(Arrays.toString(merged));
2. Java 8+:使用 IntStream.concat()(基本类型专用)

利用 Stream API 合并两个 IntStream,再转换为数组。

import java.util.stream.IntStream;

int[] merged = IntStream.concat(
    IntStream.of(arr1),  // 将 arr1 转为 IntStream
    IntStream.of(arr2)   // 将 arr2 转为 IntStream
).toArray();             // 转换回数组

二、对象数组(如 String[])合并

1. 使用 System.arraycopy()(同基本类型)
String[] arr1 = {"a", "b"};
String[] arr2 = {"c", "d"};

String[] merged = new String[arr1.length + arr2.length];
System.arraycopy(arr1, 0, merged, 0, arr1.length);
System.arraycopy(arr2, 0, merged, arr1.length, arr2.length);

// 输出:[a, b, c, d]
System.out.println(Arrays.toString(merged));
2. Java 8+:使用 Stream.concat()(通用方式)

通过 Stream.concat() 合并两个数组的 Stream。

import java.util.stream.Stream;

String[] merged = Stream.concat(
    Arrays.stream(arr1),  // 将 arr1 转为 Stream<String>
    Arrays.stream(arr2)   // 将 arr2 转为 Stream<String>
).toArray(String[]::new);  // 收集为 String[]

三、多维数组(如 int[][])合并

多维数组的合并通常指合并外层数组(例如将两个二维数组的“行”合并)。

int[][] arr1 = {{1, 2}, {3, 4}};
int[][] arr2 = {{5, 6}, {7, 8}};

// 创建新的二维数组,行数为两个原数组之和
int[][] merged = new int[arr1.length + arr2.length][];

// 复制外层数组
System.arraycopy(arr1, 0, merged, 0, arr1.length);
System.arraycopy(arr2, 0, merged, arr1.length, arr2.length);

// 输出:[[1, 2], [3, 4], [5, 6], [7, 8]]
System.out.println(Arrays.deepToString(merged));

四、合并并去重(需要手动处理)

若合并后需要去重,可结合 Set 实现(仅适用于对象数组,基本类型数组需先装箱)。

String[] arr1 = {"a", "b", "c"};
String[] arr2 = {"b", "c", "d"};

// 使用 LinkedHashSet 保持插入顺序并去重
Set<String> set = new LinkedHashSet<>();
Collections.addAll(set, arr1);  // 添加 arr1 元素
Collections.addAll(set, arr2);  // 添加 arr2 元素(重复元素自动忽略)

String[] merged = set.toArray(new String[0]);  // 转换回数组

// 输出:[a, b, c, d]
System.out.println(Arrays.toString(merged));

五、工具类封装(简化重复操作)

为避免每次合并都编写冗长代码,可封装成工具方法:

public class ArrayUtils {
    // 合并两个 int[]
    public static int[] merge(int[] arr1, int[] arr2) {
        return IntStream.concat(IntStream.of(arr1), IntStream.of(arr2)).toArray();
    }
    
    // 合并两个 String[]
    public static String[] merge(String[] arr1, String[] arr2) {
        return Stream.concat(Arrays.stream(arr1), Arrays.stream(arr2)).toArray(String[]::new);
    }
    
    // 合并任意类型数组(泛型方法)
    @SafeVarargs
    public static <T> T[] merge(T[]... arrays) {
        int totalLength = 0;
        for (T[] array : arrays) {
            totalLength += array.length;
        }
        
        // 创建新数组(需通过反射,因 Java 泛型擦除)
        T[] result = (T[]) Array.newInstance(
            arrays[0].getClass().getComponentType(), 
            totalLength
        );
        
        int destPos = 0;
        for (T[] array : arrays) {
            System.arraycopy(array, 0, result, destPos, array.length);
            destPos += array.length;
        }
        
        return result;
    }
}

使用示例

int[] mergedInts = ArrayUtils.merge(new int[]{1, 2}, new int[]{3, 4});
String[] mergedStrings = ArrayUtils.merge(new String[]{"a"}, new String[]{"b", "c"});

六、注意事项

  1. 性能考量

    • System.arraycopy() 是底层方法,性能最优,适合大规模数据合并。
    • Stream API 可读性高,但涉及装箱拆箱(基本类型)和函数式调用,性能略低。
  2. 不可变数组
    Java 数组长度固定,所有合并操作都会创建新数组,原数组保持不变。

  3. 空数组处理
    上述方法均支持空数组(length=0),无需特殊处理。

  4. 多维数组深层合并
    若需合并多维数组的内层元素(例如合并两个二维数组的列),需手动遍历并处理每个子数组。

总结

  • 基本类型数组:优先使用 System.arraycopy() 或 Java 8+ 的 IntStream.concat()
  • 对象数组:推荐使用 Stream.concat() 或工具类封装。
  • 去重需求:结合 Set 实现。
  • 性能敏感场景:直接使用 System.arraycopy() 避免额外开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值