首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 實現動態擴容數組(類似 VB ReDim Preserve 功能)

     編輯:Java 程式設計入門

背景

Java 數組長度固定,無法像 VB 的 ReDim Preserve 那樣直接擴容並保留原數據。本文提供一個通用工具方法,利用反射與 System.arraycopy 實現「創建新數組 + 複製舊數據」的動態擴容效果,支持任意類型數組(基本類型與對象類型均可)。

核心實現代碼

import java.lang.reflect.Array;

public class ArrayUtils {

    /**
     * 動態擴容數組(保留原有元素)
     *
     * @param srcArray 原數組對象(任意類型)
     * @param newLength 目標長度(必須 >= 原長度,否則拋出異常)
     * @return 擴容後的新數組,類型與原數組一致;若輸入非數組則返回 null
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] resizeArray(T[] srcArray, int newLength) {
        if (srcArray == null) {
            throw new IllegalArgumentException("源數組不能為 null");
        }
        if (newLength < srcArray.length) {
            throw new IllegalArgumentException("新長度不能小於原長度,否則會丟失數據");
        }

        // 1. 獲取數組組件類型(如 Integer.class、int.class、String.class 等)
        Class<?> componentType = srcArray.getClass().getComponentType();

        // 2. 通過反射創建同類型的新數組
        @SuppressWarnings("unchecked")
        T[] newArray = (T[]) Array.newInstance(componentType, newLength);

        // 3. 高效複製數據(原生優化,比手寫循環快得多)
        System.arraycopy(srcArray, 0, newArray, 0, srcArray.length);

        return newArray;
    }

    // ---------- 針對基本類型的重載版本(避免裝箱開銷) ----------
    public static int[]    resizeArray(int[]    src, int newLen) { return resizePrimitive(src, newLen); }
    public static long[]   resizeArray(long[]   src, int newLen) { return resizePrimitive(src, newLen); }
    public static double[] resizeArray(double[] src, int newLen) { return resizePrimitive(src, newLen); }
    public static float[]  resizeArray(float[]  src, int newLen) { return resizePrimitive(src, newLen); }
    public static char[]   resizeArray(char[]   src, int newLen) { return resizePrimitive(src, newLen); }
    public static byte[]   resizeArray(byte[]   src, int newLen) { return resizePrimitive(src, newLen); }
    public static short[]  resizeArray(short[]  src, int newLen) { return resizePrimitive(src, newLen); }
    public static boolean[] resizeArray(boolean[] src, int newLen) { return resizePrimitive(src, newLen); }

    private static <T> T resizePrimitive(T src, int newLen) {
        Class<?> comp = src.getClass().getComponentType();
        Object newArr = Array.newInstance(comp, newLen);
        System.arraycopy(src, 0, newArr, 0, ((Object[])src).length); // 基本類型數組也實現了 Object[]
        return (T) newArr;
    }
}

使用示例

public class Demo {
    public static void main(String[] args) {
        // 1. 對象數組擴容
        String[] names = {"Alice", "Bob"};
        names = ArrayUtils.resizeArray(names, 5); // 擴容至 5
        names[2] = "Charlie";
        System.out.println(String.join(", ", names)); // Alice, Bob, Charlie, null, null

        // 2. 基本類型數組擴容(無裝箱開銷)
        int[] scores = {90, 85};
        scores = ArrayUtils.resizeArray(scores, 4);
        scores[2] = 88;
        scores[3] = 92;
        // 輸出: [90, 85, 88, 92]
        System.out.println(java.util.Arrays.toString(scores));
    }
}

原理解析

  1. 反射獲取組件類型:srcArray.getClass().getComponentType() 可拿到數組元素的 Class 對象(如 Integer.class 或 int.class)。
  2. 反射創建新數組:Array.newInstance(componentType, newLength) 動態分配同類型新數組。
  3. 原生複製:System.arraycopy 是 JVM 內部優化的本地方法,複製速度極快,且自動處理基本類型與引用類型的語義差異。

最佳實踐建議

  • 優先使用 ArrayList / Vector:日常開發中,集合類已內建動態擴容、泛型支持、豐富 API,性能與開發效率雙贏。
  • 必須用數組時:僅在與底層 API 交互、極度敏感的性能熱點、或序列化協議要求固定結構時,才考慮手動擴容數組。
  • 擴容策略:參考 ArrayList 的 1.5 倍增長策略(newLen = oldLen + (oldLen >> 1)),平攤時間復雜度為 O(1)。

總結

通過反射與 System.arraycopy,我們在 Java 中實現了類似 VB ReDim Preserve 的動態數組擴容。工具類已處理基本類型與對象類型的統一入口,並提供類型安全的泛型簽名。實際項目中,除非有特殊硬性約束,仍強烈建議優先使用標準集合框架。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved