Kỹ thuật lập trình sao chép mảng (copy array) trong Java

Đây là bài 21/62 bài của series môn học Ngôn ngữ lập trình Java

1. Sao chép mảng sử dụng toán tử gán

Có thể sử dụng toán tử gán “=” để sao chép mảng trong Java.

class Main {
    public static void main(String[] args) {
        int [] numbers = {1, 2, 3, 4, 5, 6};
        int [] copyArr = numbers;
        System.out.print("Mang copyArr sao chep duoc: ");
        for (int number: copyArr) {
            System.out.print(number + " ");
        }
    }
}
Kết quả
Mang copyArr sao chep duoc: 1 2 3 4 5 6

Cách sao chép mảng sử dụng toán tử “=” rất dễ. Nhưng có một vấn đề với cách sao chép mảng này. Hãy cùng xem ví dụ bên dưới:

class Main {
    public static void main(String[] args) {
        int [] numbers = {1, 2, 3, 4, 5, 6};
        int [] copyArr = numbers;
        System.out.print("Mang copyArr sao chep duoc: ");
        for (int number: copyArr) {
            System.out.print(number + " ");
        }
        System.out.println();
        numbers[0] = -111;//thay đổi phần tử đầu tiên trong mảng numbers
        System.out.print("Mang copyArr sau khi mang numbers thay doi: ");
        for (int number: copyArr) {
            System.out.print(number + " ");
        }
    }
}
Kết quả
Mang copyArr sao chep duoc: 1 2 3 4 5 6 
Mang copyArr sau khi mang numbers thay doi: -111 2 3 4 5 6

Rõ ràng, khi thay đổi mảng numbers thì mảng copyArr cũng thay đổi theo. Điều này có nghĩa là, khi sử dụng toán tử gán “=” để sao chép mảng thì không có mảng mới nào được tạo ra. Tên biến mảng numberscopyArr tham chiếu đến cùng một vùng nhớ lưu trữ của mảng. Hiện tượng này gọi là sao chép nông (shallow copy).

2. Gán từng phần tử của mảng này vào mảng kia

Để tránh hiện tượng sao chép nông (shallow copy), chúng ta sẽ khai báo và cấp phát bộ nhớ cho một mảng mới. Sau đó, copy từng phần tử của mảng đã có sang mảng mới vừa khai báo.

class Main {
    public static void main(String[] args) {
        int [] numbers = {1, 2, 3, 4, 5, 6};
        int [] copyArr = new int[6];
        //sao chép mảng numbers vào mảng copyArr
        for (int i = 0; i < numbers.length; ++i) {
            copyArr[i] = numbers[i];
        }
        System.out.print("Mang copyArr sao chep duoc: ");
        for (int number: copyArr) {
            System.out.print(number + " ");
        }
    }
}
Kết quả
Mang copyArr sao chep duoc: 1 2 3 4 5 6

Mảng numberscopyArr có 2 vùng nhớ lưu trữ mảng khác nhau. Hiện tượng này gọi là sao chép sâu (deep copy).

3. Sao chép mảng sử dụng hàm arraycopy()

Trong Java, lớp java.lang.System có hỗ trợ hàm arraycopy() để sao chép mảng. Hàm arrayycopy() cho phép sao chép một phần cụ thể của mảng nguồn sang mảng đích. Cú pháp của hàm arraycopy():

arraycopy(Object src, int srcPos,Object dest, int destPos, int length)

Trong đó,

  • src là mảng nguồn muốn sao chép
  • srcPos là vị trí phần tử bắt đầu sẽ sao chép trên mảng nguồn
  • dest là mảng đích muốn sao chép từ mảng nguồn sang mảng đích
  • destPos là vị trí phần tử bắt đầu trên mảng đích mà mảng nguồn sao chép sang
  • length là số phần tử muốn sao chép từ mảng nguồn sang mảng đích

Ví dụ:

class Main {
    public static void main(String[] args) {
        int [] numbers = {1, 2, 3, 4, 5, 6};
        int [] copyArr1 = new int[5];
        int [] copyArr2 = new int[numbers.length];
        System.arraycopy(numbers, 2, copyArr1, 1, 3);
        System.out.print("Mang copyArr1 sao chep duoc: ");
        for (int number: copyArr1) {
            System.out.print(number + " ");
        }
        System.out.println();
        System.arraycopy(numbers, 0, copyArr2, 0, numbers.length);
        System.out.print("Mang copyArr2 sao chep duoc: ");
        for (int number: copyArr2) {
            System.out.print(number + " ");
        }
    }
}
Kết quả
Mang copyArr1 sao chep duoc: 0 3 4 5 0 
Mang copyArr2 sao chep duoc: 1 2 3 4 5 6

System.arraycopy(numbers, 2, copyArr1, 1, 3); thì 3 phần tử trong mảng numbers bắt đầu từ index = 2 sẽ được copy đến mảng copyArr1 tại index=1. Mảng copyArr1 có các phần tử có giá trị là 0 vì chúng là giá trị mặc định của kiểu int.

System.arraycopy(numbers, 0, copyArr2, 0, numbers.length); thì tất cả các phần tử của mảng numbers được sao chép cho mảng copyArr2.

4. Sao chép mảng sử dụng hàm copyOfRange()

Chúng ta cũng có thể sử dụng hàm copyOfRange() trong lớp java.util.Arrays để sao chép mảng. Hàm copyOfRange() trả về một mảng sao chép được. Ví dụ:

import java.util.Arrays;
class Main {
    public static void main(String[] args) {
        int [] numbers = {1, 2, 3, 4, 5, 6};
        //sao chép toàn bộ mảng numbers
        int [] copyArr1 = Arrays.copyOfRange(numbers, 0, numbers.length);
        System.out.print("Mang copyArr1 sao chep duoc: ");
        for (int number: copyArr1) {
            System.out.print(number + " ");
        }
        System.out.println();
        //sao chép mảng numbers từ index 2 đến 5 (không bao gồm index=5)
        int [] copyArr2 = Arrays.copyOfRange(numbers, 2, 5);
        System.out.print("Mang copyArr2 sao chep duoc: ");
        for (int number: copyArr2) {
            System.out.print(number + " ");
        }
    }
}
Kết quả
Mang copyArr1 sao chep duoc: 1 2 3 4 5 6 
Mang copyArr2 sao chep duoc: 3 4 5

5. Sao chép mảng 2 chiều

Sử dụng 2 vòng lặp for lồng nhau để duyệt mảng 2 chiều và copy mảng 2 chiều này sang mảng 2 chiều kia.

import java.util.Arrays;
class Main {
    public static void main(String[] args) {
        int[][] source = {
            {1, 2, 3, 4}, 
            {5, 6},
            {0, 2, 42, -4, 5}
        };
        int[][] dest = new int[source.length][];
        for (int i = 0; i < dest.length; ++i) {
            dest[i] = new int[source[i].length];
            for (int j = 0; j < dest[i].length; ++j) {
                dest[i][j] = source[i][j];
            }
        }
        System.out.print("Mang 2 chieu sao chep duoc:");
        System.out.println(Arrays.deepToString(dest));
    }
}
Kết quả
Mang 2 chieu sao chep duoc:[[1, 2, 3, 4], [5, 6], [0, 2, 42, -4, 5]]

Hàm Arrays.deepToString() chuyển mảng nhiều chiều thành chuỗi String.

3.1/5 - (7 bình chọn)
Bài trước và bài sau trong môn học<< Kỹ thuật lập trình với mảng 2 chiều trong JavaLớp (class) và cách xây dựng lớp trong Java >>
Chia sẻ trên mạng xã hội:

Trả lời

Lưu ý:

1) Vui lòng bình luận bằng tiếng Việt có dấu.

2) Khuyến khích sử dụng tên thật và địa chỉ email chính xác.

3) Mọi bình luận trái quy định sẽ bị xóa bỏ.