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 numbers và copyArr 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 numbers và copyArr 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épsrcPos
là vị trí phần tử bắt đầu sẽ sao chép trên mảng nguồndest
là mảng đích muốn sao chép từ mảng nguồn sang mảng đíchdestPos
là vị trí phần tử bắt đầu trên mảng đích mà mảng nguồn sao chép sanglength
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.