"

ادغام دو آرایه در جاوا (Merge Two Arrays in Java),مزایای System.arraycopy نسبت به حلقه for,اجزای Stream API در جاوا

ادغام دو آرایه در جاوا (Merge Two Arrays in Java)

ادغام دو آرایه در جاوا (Merge Two Arrays in Java) یعنی ترکیب دو آرایه در یکی با حلقه for، System.arraycopy یا Stream API.

تیم تحریریه
6
0
20 اردیبهشت 1405
لینک کوتاه

ادغام دو آرایه در جاوا (Merge Two Arrays in Java)

در زبان برنامه‌نویسی جاوا، آرایه‌ها ساختارهایی با اندازه ثابت هستند.
یکی از عملیات‌های رایج هنگام کار با آرایه‌ها، ادغام (Merge) کردن دو آرایه در یک آرایه جدید است.
این عمل به معنای گرفتن تمام عناصر از دو آرایه مختلف و قرار دادن آن‌ها در کنار هم در یک آرایه واحد می‌باشد.

جاوا برخلاف برخی زبان‌های دیگر مانند پایتون یا جاوااسکریپت، متد توکاری به نام concat برای آرایه‌ها ندارد.
بنابراین برنامه‌نویس باید منطق ادغام را به صورت دستی پیاده‌سازی کند.
خوشبختانه روش‌های متعددی برای این کار وجود دارد .

ادغام دو آرایه در جاوا (Merge Two Arrays in Java)

روش اول: ادغام با استفاده از حلقه for

ساده‌ترین و ابتدایی‌ترین روش برای ترکیب دو آرایه، استفاده از حلقه for است.
این روش به شما کنترل کامل روی اندیس‌ها می‌دهد و درک آن برای مبتدیان بسیار آسان است.

کد مثال پایه


public class MergeWithForLoop {
    public static void main(String[] args) {
        // تعریف دو آرایه صحیح
        int[] array1 = {1, 2, 3, 4};
        int[] array2 = {5, 6, 7, 8, 9};
        
        // ایجاد آرایه جدید با اندازه مجموع دو آرایه
        int[] mergedArray = new int[array1.length + array2.length];
        
        // کپی عناصر آرایه اول
        for (int i = 0; i < array1.length; i++) {
            mergedArray[i] = array1[i];
        }
        
        // کپی عناصر آرایه دوم - ادامه از انتهای آرایه اول
        for (int i = 0; i < array2.length; i++) {
            mergedArray[array1.length + i] = array2[i];
        }
        
        // چاپ نتیجه
        System.out.print("آرایه ادغام شده: ");
        for (int num : mergedArray) {
            System.out.print(num + " ");
        }
    }
}

خروجی:

آرایه ادغام شده: 1 2 3 4 5 6 7 8 9

توضیح دقیق کد

  • ابتدا دو آرایه مبدأ تعریف می‌شوند (array1 و array2).
  • آرایه جدید به نام mergedArray با طولی برابر با array1.length + array2.length ایجاد می‌شود.
  • در حلقه اول، عناصر array1 به ترتیب در موقعیت‌های ۰ تا array1.length-1 آرایه مقصد قرار می‌گیرند.
  • در حلقه دوم، عناصر array2 از اندیس array1.length به بعد در آرایه مقصد کپی می‌شوند.
    فرمول array1.length + i دقیقاً موقعیت مناسب را مشخص می‌کند.




🚀 از صفر تا قهرمان جاوا، فقط با یک دوره!
به دنبال یه فرصت طلایی برای شروع برنامه‌نویسی می‌گردی؟
دوره آموزشی جاوا ما، همون چیزیه که نیاز داری!

✨ چرا این دوره رو انتخاب می‌کنی؟
🎯 از مبتدی تا حرفه‌ای
بدون پیش‌زمینه شروع می‌کنی و به یه برنامه‌نویس جاوا تبدیل می‌شی که بازار کار منتظرته!

🛠 پروژه‌محور و عملی
با انجام پروژه‌های واقعی، کدنویسی رو یاد می‌گیری، نه فقط تئوری!

👨‍🏫 پشتیبانی همیشگی
هرجا گیر کنی، تیم پشتیبانی کنارته تا مشکلت حل بشه.

🔓 دسترسی مادام‌العمر
هر وقت خواستی به محتوا دسترسی داری، برای همیشه!

 

🔥 همین حالا ثبت‌نام کن 







کار با انواع داده‌های مختلف

این روش برای تمام نوع‌های داده قابل استفاده است.
کافی است نوع آرایه را تغییر دهید:
// ادغام آرایه رشته‌ای
String[] names1 = {"احمد", "رضا", "سارا"};
String[] names2 = {"مهدی", "نرگس"};
String[] allNames = new String[names1.length + names2.length];

for (int i = 0; i < names1.length; i++) {
    allNames[i] = names1[i];
}
for (int i = 0; i < names2.length; i++) {
    allNames[names1.length + i] = names2[i];
}

// ادغام آرایه اعشاری
double[] doubles1 = {1.5, 2.5, 3.5};
double[] doubles2 = {4.5, 5.5};
double[] mergedDoubles = new double[doubles1.length + doubles2.length];

for (int i = 0; i < doubles1.length; i++) {
    mergedDoubles[i] = doubles1[i];
}
for (int i = 0; i < doubles2.length; i++) {
    mergedDoubles[doubles1.length + i] = doubles2[i];
}

روش دوم: ادغام با استفاده از System.arraycopy

متد System.arraycopy() یک متد بومی (native) در جاوا است که برای کپی کردن بلوک‌های حافظه بهینه شده است.
این روش از نظر کارایی بسیار سریع‌تر از حلقه for عمل می‌کند، مخصوصاً زمانی که آرایه‌ها بزرگ هستند.

آشنایی با سینتکس System.arraycopy

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


پارامتر  توضیح
src آرایه منبع (مبدأ)
srcPos اندیس شروع در آرایه منبع
dest    آرایه مقصد
destPos اندیس شروع در آرایه مقصد
length   تعداد عناصری که باید کپی شوند

کد مثال

public class MergeWithArrayCopy {
    public static void main(String[] args) {
        int[] firstArray = {10, 20, 30, 40};
        int[] secondArray = {50, 60, 70};
        
        // ایجاد آرایه جدید
        int[] resultArray = new int[firstArray.length + secondArray.length];
        
        // کپی آرایه اول به نتیجه
        System.arraycopy(firstArray, 0, resultArray, 0, firstArray.length);
        
        // کپی آرایه دوم به نتیجه (ادامه از انتهای آرایه اول)
        System.arraycopy(secondArray, 0, resultArray, firstArray.length, secondArray.length);
        
        // نمایش نتیجه
        System.out.print("نتیجه ادغام: ");
        for (int value : resultArray) {
            System.out.print(value + " ");
        }
    }
}

خروجی:

نتیجه ادغام: 10 20 30 40 50 60 70



مزایای System.arraycopy نسبت به حلقه for

  • سرعت بالاتر

    این متد مستقیماً توسط ماشین مجازی جاوا بهینه می‌شود و از کپی سطح پایین حافظه استفاده می‌کند.
  • کد مختصرتر

    تنها دو خط کد برای کپی کردن هر دو آرایه نیاز است.
  • کاهش خطا

    احتمال اشتباه در محاسبه اندیس‌ها کمتر است.

مزایای System.arraycopy نسبت به حلقه for


مثال با آرایه از نوع Object

// ادغام آرایه از نوع Integer (کلاس wrapper)
Integer[] boxedArray1 = {100, 200, 300};
Integer[] boxedArray2 = {400, 500};
Integer[] mergedBoxed = new Integer[boxedArray1.length + boxedArray2.length];

System.arraycopy(boxedArray1, 0, mergedBoxed, 0, boxedArray1.length);
System.arraycopy(boxedArray2, 0, mergedBoxed, boxedArray1.length, boxedArray2.length);

روش سوم: ادغام با استفاده از Stream API (جاوا ۸ و بالاتر)

از جاوا ۸ به بعد، API جدیدی به نام Stream معرفی شد که امکان کار با مجموعه داده‌ها را به صورت تابعی (Functional) فراهم می‌کند.
این روش خوانایی بسیار بالایی دارد و کد بسیار تمیز و مدرنی ارائه می‌دهد.

ادغام آرایه‌های اولیه (int, double, long)

برای آرایه‌های اولیه، متدهای خاصی مانند IntStream، DoubleStream و LongStream وجود دارند:

import java.util.Arrays;
import java.util.stream.IntStream;

public class MergeWithStreams {
    public static void main(String[] args) {
        int[] numbers1 = {2, 4, 6, 8};
        int[] numbers2 = {10, 12, 14, 16, 18};
        
        // تبدیل هر آرایه به IntStream و سپس ادغام با concat
        int[] mergedNumbers = IntStream.concat(
                Arrays.stream(numbers1),
                Arrays.stream(numbers2)
            ).toArray();
        
        // چاپ نتیجه با استفاده از Arrays.toString
        System.out.println(Arrays.toString(mergedNumbers));
    }
}

خروجی:

[2, 4, 6, 8, 10, 12, 14, 16, 18]

ادغام آرایه‌های از نوع String (یا هر Object دیگر)

برای آرایه‌های شیء (مانند String، Integer، و کلاس‌های سفارشی) از Stream.concat استفاده می‌شود:


import java.util.Arrays;
import java.util.stream.Stream;

public class MergeStringArrays {
    public static void main(String[] args) {
        String[] fruits1 = {"سیب", "پرتقال", "موز"};
        String[] fruits2 = {"انگور", "هندوانه", "کیوی", "گلابی"};
        
        // ادغام دو آرایه رشته‌ای
        String[] allFruits = Stream.concat(
                Arrays.stream(fruits1),
                Arrays.stream(fruits2)
            ).toArray(String[]::new);
        
        System.out.println(Arrays.toString(allFruits));
    }
}

خروجی:

[سیب, پرتقال, موز, انگور, هندوانه, کیوی, گلابی]

اجزای Stream API در جاوا

  • Arrays.stream(آرایه)

    آرایه ورودی را به یک Stream تبدیل می‌کند.
  • IntStream.concat(stream1, stream2)

    دو استریم از نوع اولیه صحیح را به هم متصل می‌کند.
  • Stream.concat(stream1, stream2)

    دو استریم از نوع شیء را به هم متصل می‌کند.
  • ()toArray

    استریم نهایی را به آرایه تبدیل می‌کند.
  • toArray(String[]::new)

    برای تبدیل استریم به آرایه با نوع مشخص، باید یک سازنده آرایه ارائه داد.



اجزای Stream API در جاوا

روش چهارم: ادغام با استفاده از ArrayList و تبدیل به آرایه

اگر با مجموعه‌های پویا مانند ArrayList آشنایی دارید، می‌توانید از این روش استفاده کنید.
این روش مخصوصاً زمانی مفید است که نمی‌دانید تعداد نهایی عناصر چقدر است یا می‌خواهید بعد از ادغام نیز عملیات افزودن/حذف انجام دهید.

کد مثال

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MergeWithArrayList {
    public static void main(String[] args) {
        // توجه: برای آرایه اولیه (مثل int) باید از کلاس wrapper استفاده کرد
        Integer[] arr1 = {5, 10, 15};
        Integer[] arr2 = {20, 25, 30, 35};
        
        // ایجاد ArrayList و اضافه کردن عناصر آرایه اول
        List<Integer> list = new ArrayList<>();
        list.addAll(Arrays.asList(arr1));
        
        // اضافه کردن عناصر آرایه دوم
        list.addAll(Arrays.asList(arr2));
        
        // تبدیل ArrayList به آرایه
        Integer[] mergedArray = list.toArray(new Integer[0]);
        
        System.out.println(Arrays.toString(mergedArray));
    }
}

خروجی:

[5, 10, 15, 20, 25, 30, 35]


نکته مهم درباره آرایه‌های اولیه

روش فوق برای نوع‌های اولیه مانند []int مستقیم کار نمی‌کند، زیرا ()Arrays.asList با آرایه‌های اولیه رفتار متفاوتی دارد.
اگر نیاز به ادغام []int با این روش دارید، راه حل زیر را استفاده کنید:

int[] primitiveArray1 = {1, 2, 3};
int[] primitiveArray2 = {4, 5, 6};

List<Integer> intList = new ArrayList<>();
for (int num : primitiveArray1) intList.add(num);
for (int num : primitiveArray2) intList.add(num);

Integer[] result = intList.toArray(new Integer[0]);


روش پنجم: ادغام آرایه‌های مرتب شده (Sorted Array Merge)

سناریوی خاصی که در الگوریتم‌ها بسیار رایج است، ادغام دو آرایه مرتب شده به گونه‌ای است که آرایه خروجی نیز مرتب باشد.
این الگوریتم هسته اصلی مرتب‌سازی ادغامی (Merge Sort) را تشکیل می‌دهد.

الگوریتم ادغام دو آرایه مرتب شده


import java.util.Arrays;

public class MergeSortedArrays {
    public static void main(String[] args) {
        // هر دو آرایه ورودی مرتب شده‌اند
        int[] sortedArray1 = {1, 3, 5, 7, 9};
        int[] sortedArray2 = {2, 4, 6, 8, 10, 12};
        
        int[] mergedSorted = mergeSortedArrays(sortedArray1, sortedArray2);
        System.out.println(Arrays.toString(mergedSorted));
    }
    
    public static int[] mergeSortedArrays(int[] a, int[] b) {
        int[] result = new int[a.length + b.length];
        int i = 0; // اندیس برای آرایه a
        int j = 0; // اندیس برای آرایه b
        int k = 0; // اندیس برای آرایه result
        
        // مقایسه عناصر دو آرایه و قرار دادن کوچکترین در نتیجه
        while (i < a.length && j < b.length) {
            if (a[i] <= b[j]) {
                result[k++] = a[i++];
            } else {
                result[k++] = b[j++];
            }
        }
        
        // کپی عناصر باقیمانده از آرایه اول (اگر وجود داشته باشد)
        while (i < a.length) {
            result[k++] = a[i++];
        }
        
        // کپی عناصر باقیمانده از آرایه دوم (اگر وجود داشته باشد)
        while (j < b.length) {
            result[k++] = b[j++];
        }
        
        return result;
    }
}

خروجی:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]

تحلیل پیچیدگی زمانی

این الگوریتم دارای پیچیدگی زمانی O(n + m) است که در آن n و m به ترتیب طول دو آرایه هستند.
این الگوریتم بهینه‌ترین روش برای ادغام دو آرایه مرتب شده محسوب می‌شود.

روش ششم: نوشتن یک متد Generic برای ادغام هر نوع آرایه

اگر می‌خواهید یک متد جهانی بسازید که با هر نوع آرایه‌ای (از هر کلاسی) کار کند، از Generics در جاوا استفاده کنید:

import java.util.Arrays;

public class GenericArrayMerger {
    
    /**
     * متد عمومی برای ادغام دو آرایه از یک نوع
     * @param array1 آرایه اول
     * @param array2 آرایه دوم
     * @return آرایه ادغام شده
     */
    public static <T> T[] merge(T[] array1, T[] array2) {
        // ایجاد آرایه جدید با استفاده از copyOf
        T[] result = Arrays.copyOf(array1, array1.length + array2.length);
        // کپی آرایه دوم
        System.arraycopy(array2, 0, result, array1.length, array2.length);
        return result;
    }
    
    public static void main(String[] args) {
        // آزمون با آرایه رشته‌ای
        String[] str1 = {"Java", "Python"};
        String[] str2 = {"C++", "JavaScript", "Go"};
        String[] mergedStr = merge(str1, str2);
        System.out.println("ادغام رشته‌ها: " + Arrays.toString(mergedStr));
        
        // آزمون با آرایه از کلاس Integer
        Integer[] int1 = {10, 20, 30};
        Integer[] int2 = {40, 50};
        Integer[] mergedInt = merge(int1, int2);
        System.out.println("ادغام اعداد: " + Arrays.toString(mergedInt));
    }
}

خروجی:


ادغام رشته‌ها: [Java, Python, C++, JavaScript, Go]
ادغام اعداد: [10, 20, 30, 40, 50]


نکته مهم: متد Generic فوق فقط با آرایه‌های شیء کار می‌کند و برای نوع‌های اولیه (int[]، double[] و غیره) قابل استفاده نیست.

 

نکات فنی و خطاهای رایج ادغام دو آرایه در جاوا 

۱. خطای ArrayIndexOutOfBoundsException

این خطا زمانی رخ می‌دهد که آرایه مقصد به اندازه کافی بزرگ نباشد:
// کد اشتباه
int[] a = {1, 2};
int[] b = {3, 4};
int[] result = new int[3]; // اندازه ۳ کافی نیست (نیاز به ۴ دارد)
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length); // خطا: اندیس ۳ خارج از محدوده



راه حل: همیشه آرایه مقصد را با اندازه array1.length + array2.length ایجاد کنید.

۲. همپوشانی (Overlap) در System.arraycopy

اگر آرایه مبدأ و مقصد یکی باشند و محدوده‌ها همپوشانی داشته باشند، رفتار متد تعریف شده است اما باید دقت کنید:
int[] arr = {1, 2, 3, 4, 5};
// کپی از اندیس ۲ به اندیس ۱ - ترتیب کپی مهم است
System.arraycopy(arr, 2, arr, 1, 3); // نتیجه: [1, 3, 4, 5, 5]


۳. آرایه‌های خالی (Empty Arrays)

کدهای ما با آرایه‌های خالی (طول صفر) نیز به درستی کار می‌کنند.
آرایه خالی هیچ عنصری برای کپی ندارد و حلقه‌ها یا arraycopy با طول صفر چیزی انجام نمی‌دهند.


نکات فنی و خطاهای رایج ادغام دو آرایه در جاوا 


مثال‌های عملی و کاربردی

مثال ۱: ادغام لیست نمرات دانشجویان دو ترم


int[] term1Scores = {85, 92, 78, 88};
int[] term2Scores = {90, 87, 94, 81, 79};
int[] allScores = new int[term1Scores.length + term2Scores.length];

System.arraycopy(term1Scores, 0, allScores, 0, term1Scores.length);
System.arraycopy(term2Scores, 0, allScores, term1Scores.length, term2Scores.length);

System.out.println("کل نمرات: " + Arrays.toString(allScores));
// خروجی: کل نمرات: [85, 92, 78, 88, 90, 87, 94, 81, 79]

مثال ۲: ترکیب دو آرایه از محصولات فروشگاه

String[] winterProducts = {"ژاکت", "شال", "دستکش"};
String[] summerProducts = {"عینک آفتابی", "کلاه لبه‌دار", "صندل"};
String[] allProducts = Stream.concat(
    Arrays.stream(winterProducts),
    Arrays.stream(summerProducts)
).toArray(String[]::new);

System.out.println("همه محصولات: " + Arrays.toString(allProducts));
// خروجی: همه محصولات: [ژاکت, شال, دستکش, عینک آفتابی, کلاه لبه‌دار, صندل]



جمع‌بندی نهایی

روش‌های موجود برای ادغام دو آرایه در جاوا  شامل:

روش مبتنی بر حلقه for برای درک ساده الگوریتم

روش System.arraycopy به عنوان سریع‌ترین و حرفه‌ای‌ترین راه‌حل

روش Stream API برای کدنویسی مدرن و تابعی

روش ArrayList برای انعطاف‌پذیری بیشتر

الگوریتم ادغام آرایه‌های مرتب شده برای کاربردهای الگوریتمی

متد Generic برای ایجاد راه‌حل قابل استفاده مجدد

برای پروژه‌های واقعی، استفاده از System.arraycopy() به دلیل سرعت و کارایی بالا توصیه می‌شود. اگر از جاوا ۸ یا بالاتر استفاده می‌کنید و خوانایی کد برای شما اولویت دارد، Stream API انتخاب بسیار مناسبی است. مبتدیان می‌توانند با حلقه for شروع کنند تا درک عمیق‌تری از نحوه کار با اندیس‌های آرایه پیدا کنند.

تمام کدهای ارائه شده در این مقاله قابل کامپایل و اجرا هستند و می‌توانید آن‌ها را در پروژه‌های خود استفاده کنید.

محصولات مرتبط

کاربران ما

شما هم نظرتون با ما دریاره “ادغام دو آرایه در جاوا (Merge Two Arrays in Java)” اشتراک بزارید

برای ارسال نظر لطفا ورود یا ثبت نام کنید

منو