Penugasan antar array di Java tidak menyalin isi — penugasan menyalin referensinya. Pemula yang belum menyadari hal tersebut sering mengubah data lewat variabel kedua, lalu kaget karena array aslinya ikut berubah. Chapter ini membedah perbedaan referensi versus salinan, lalu menyajikan tiga cara menyalin array: perulangan manual, System.arraycopy, dan Arrays.copyOf dari class utilitas java.util.Arrays.
Penugasan Menyalin Referensi Bukan Isi #
Variabel array adalah penunjuk ke objek array di heap. Ketika kita menulis alias = asli, JVM menyalin alamat objek, bukan objeknya — kedua variabel kini menunjuk array yang sama. Perubahan melalui salah satu variabel terlihat dari variabel lain karena keduanya membaca slot memori yang identik.
import java.util.Arrays;
public class ReferensiVsSalinan {
public static void main(String[] args) {
int[] asli = {1, 2, 3};
int[] alias = asli;
alias[0] = 99;
System.out.println("asli : " + Arrays.toString(asli));
System.out.println("alias : " + Arrays.toString(alias));
int[] salinan = new int[asli.length];
for (int i = 0; i < asli.length; i++) {
salinan[i] = asli[i];
}
salinan[0] = 7;
System.out.println("asli setelah salinan diubah: " + Arrays.toString(asli));
System.out.println("salinan setelah diubah : " + Arrays.toString(salinan));
}
}Output yang Dihasilkan:
asli : [99, 2, 3]
alias : [99, 2, 3]
asli setelah salinan diubah: [99, 2, 3]
salinan setelah diubah : [7, 2, 3]Mari kita telaah baris-baris kode di atas:
- Baris 7 (
int[] alias = asli;): tidak adanew, sehingga tidak ada array baru. JVM menyalin referensi;aliasdanaslikini menunjuk objek array yang sama. - Baris 8 (
alias[0] = 99;): mengubah slot pertama dari objek bersama tersebut. Baris 9-10 membuktikan kedua variabel menampilkan[99, 2, 3]— satu objek, dua nama. - Baris 12-15 (perulangan manual): cara paling dasar membuat salinan sungguhan — buat array baru dengan ukuran sama, lalu pindahkan nilai elemen satu per satu. Array ini menempati memori terpisah.
- Baris 16 (
salinan[0] = 7;): mengubah salinan saja. Baris 17-18 menunjukkanaslitetap[99, 2, 3]sementarasalinanmenjadi[7, 2, 3]— dua objek independen.
Tiga Alat Salinan Bawaan JDK #
Perulangan manual sah, tetapi JDK menyediakan jalur lebih ringkas. System.arraycopy(sumber, indeksSumber, tujuan, indeksTujuan, jumlah) menyalin sebagian atau seluruh elemen dengan satu panggilan method native yang cepat. Arrays.copyOf(asli, panjangBaru) membuat array baru berukuran bebas — bila panjang baru lebih besar, slot tambahan diisi nilai default. Arrays.copyOfRange(asli, dari, sampai) mengambil irisan dari indeks dari (termasuk) hingga sampai (tidak termasuk).
Masih ada satu jalur lagi yang jarang disebut: method clone() pada array, misalnya int[] salin = data.clone(). Method tersebut mengembalikan array baru dengan tipe dan isi yang sama persis dengan sumbernya — jalur tercepat untuk salinan utuh ketika kita tidak butuh mengubah ukuran maupun mengambil irisan. Sama seperti tiga alat lainnya, clone() melakukan shallow copy: untuk array berisi referensi objek, objek yang ditunjuk tetap dibagikan.
import java.util.Arrays;
public class SalinanArray {
public static void main(String[] args) {
int[] data = {10, 20, 30, 40, 50};
int[] semua = Arrays.copyOf(data, data.length);
int[] lebih = Arrays.copyOf(data, 7);
int[] potong = Arrays.copyOfRange(data, 1, 4);
int[] tujuan = new int[5];
System.arraycopy(data, 0, tujuan, 1, 4);
System.out.println("copyOf(asli, 5) : " + Arrays.toString(semua));
System.out.println("copyOf(asli, 7) : " + Arrays.toString(lebih));
System.out.println("copyOfRange(1,4): " + Arrays.toString(potong));
System.out.println("arraycopy : " + Arrays.toString(tujuan));
}
}Output yang Dihasilkan:
copyOf(asli, 5) : [10, 20, 30, 40, 50]
copyOf(asli, 7) : [10, 20, 30, 40, 50, 0, 0]
copyOfRange(1,4): [20, 30, 40]
arraycopy : [0, 10, 20, 30, 40]Penjelasan hasil per baris kunci:
- Baris 6 (
Arrays.copyOf(data, 5)): salinan utuh berukuran sama, hasil[10, 20, 30, 40, 50]. - Baris 7 (
Arrays.copyOf(data, 7)): kapasitas baru7melebihi panjang sumber, sehingga dua slot ekstra diisi default0— hasil[10, 20, 30, 40, 50, 0, 0]. Perilaku ini praktis untuk “memperbesar” array yang ukurannya beku. - Baris 8 (
Arrays.copyOfRange(data, 1, 4)): mengambil elemen indeks1,2,3(indeks4tidak ikut), menghasilkan[20, 30, 40]. - Baris 10-11 (
System.arraycopy): menyalin4elemen mulai indeks sumber0ke tujuan mulai indeks1. Slottujuan[0]tidak tersentuh sehingga tetap0, hasil[0, 10, 20, 30, 40]. Method ini cocok saat array tujuan sudah tersedia dan kita ingin menempatkan data pada posisi tertentu.
Satu catatan untuk array multidimensi dan array berisi objek: ketiga alat tersebut melakukan shallow copy — elemen baris atau referensi objek tetap dibagikan. Mengubah salinan[0][0] pada salinan array dua dimensi tetap terlihat dari array asal karena array barisnya masih objek yang sama. Bila kemandirian penuh dibutuhkan, salin tiap baris secara terpisah.
Setelah menyalin data, langkah produktif berikutnya adalah mengolahnya: mencetak dengan rapi, mengurutkan, lalu mencari isinya — tugas class Arrays yang kita bahas pada Chapter Array Utilities.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
ReferensiVsSalinan.java
Unduh berkasimport java.util.Arrays;
public class ReferensiVsSalinan {
public static void main(String[] args) {
int[] asli = {1, 2, 3};
int[] alias = asli;
alias[0] = 99;
System.out.println("asli : " + Arrays.toString(asli));
System.out.println("alias : " + Arrays.toString(alias));
int[] salinan = new int[asli.length];
for (int i = 0; i < asli.length; i++) {
salinan[i] = asli[i];
}
salinan[0] = 7;
System.out.println("asli setelah salinan diubah: " + Arrays.toString(asli));
System.out.println("salinan setelah diubah : " + Arrays.toString(salinan));
}
}
SalinanArray.java
Unduh berkasimport java.util.Arrays;
public class SalinanArray {
public static void main(String[] args) {
int[] data = {10, 20, 30, 40, 50};
int[] semua = Arrays.copyOf(data, data.length);
int[] lebih = Arrays.copyOf(data, 7);
int[] potong = Arrays.copyOfRange(data, 1, 4);
int[] tujuan = new int[5];
System.arraycopy(data, 0, tujuan, 1, 4);
System.out.println("copyOf(asli, 5) : " + Arrays.toString(semua));
System.out.println("copyOf(asli, 7) : " + Arrays.toString(lebih));
System.out.println("copyOfRange(1,4): " + Arrays.toString(potong));
System.out.println("arraycopy : " + Arrays.toString(tujuan));
}
}