Membandingkan Array di Jawa

1. Ikhtisar

Dalam tutorial ini, kita akan melihat berbagai cara untuk membandingkan array di Java . Kami akan membahas metode konvensional, dan kami juga akan melihat beberapa contoh menggunakan ekspresi lambda .

2. Membandingkan Array

Kita akan membandingkan array di Java, dan seperti yang kita ketahui, ini adalah objek. Oleh karena itu, mari kita segarkan beberapa konsep dasar:

  • Objek memiliki referensi dan nilai
  • Dua referensi yang sama harus menunjuk ke nilai yang sama
  • Dua nilai yang berbeda harus memiliki referensi yang berbeda
  • Dua nilai yang sama tidak selalu memiliki referensi yang sama
  • Nilai primitif hanya dibandingkan per nilai
  • Literal string hanya dibandingkan per nilai

2.1. Membandingkan Referensi Objek

Jika kita memiliki dua referensi yang menunjuk ke array yang sama, kita harus selalu mendapatkan hasil yang benar dalam perbandingan yang sama dengan operator == .

Mari kita lihat contohnya:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = planes1;

Pertama, kami membuat larik model bidang yang direferensikan oleh planes1 . Kami kemudian membuat planes2 , yang mereferensikan planes1 . Dengan melakukan ini, kami membuat dua referensi ke array yang sama di memori . Oleh karena itu, ekspresi "planes1 == planes2" akan mengembalikan nilai true .

Untuk array, metode equals () sama dengan operator == . Jadi, planes1.equals (planes2) mengembalikan nilai true karena kedua referensi merujuk ke objek yang sama. Secara umum, array1.eqauls (array2) akan mengembalikan nilai true jika dan hanya jika ekspresi " array1 == array2 ″ mengembalikan true .

Mari kita tegaskan jika kedua referensi itu sama:

assertThat(planes1).isSameAs(planes2);

Sekarang mari kita pastikan bahwa nilai yang direferensikan oleh planes1 sebenarnya sama dengan yang direferensikan oleh planes2 . Oleh karena itu, kita dapat mengubah array yang direferensikan oleh planes2, dan memeriksa apakah perubahan tersebut berdampak pada array yang direferensikan oleh planes1 :

planes2[0] = "747";

Untuk akhirnya melihat ini bekerja, mari buat pernyataan kita:

assertThat(planes1).isSameAs(planes2); assertThat(planes2[0]).isEqualTo("747"); assertThat(planes1[0]).isEqualTo("747");

Dengan pengujian unit ini, kami dapat membandingkan dua array dengan referensi.

Namun, kami hanya membuktikan bahwa satu referensi, setelah ditetapkan ke nilai lain, akan mereferensikan nilai yang sama.

Sekarang kita akan membuat dua array berbeda dengan nilai yang sama:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" };

Karena mereka adalah objek yang berbeda, kita tahu pasti bahwa keduanya tidak sama. Oleh karena itu, kami dapat membandingkannya:

assertThat(planes1).isNotSameAs(planes2);

Singkatnya, dalam kasus ini, kita memiliki dua array dalam memori yang berisi nilai String yang sama dalam urutan yang persis sama. Namun, tidak hanya array yang direferensikan berbeda dalam konten, tetapi referensinya sendiri juga berbeda.

2.2. Membandingkan Panjang Array

Panjang array dapat dibandingkan terlepas dari jenis elemennya, atau apakah nilainya diisi atau tidak .

Mari buat dua array:

final String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; final Integer[] quantities = new Integer[] { 10, 12, 34, 45, 12, 43, 5, 2 };

Ini adalah dua array berbeda dengan tipe elemen berbeda. Dalam kumpulan data ini, kami mendaftarkan, sebagai contoh, berapa banyak pesawat dari setiap model yang disimpan di gudang. Sekarang mari kita jalankan pengujian unit pada mereka:

assertThat(planes1).hasSize(8); assertThat(quantities).hasSize(8);

Dengan ini, kami telah membuktikan bahwa kedua array memiliki delapan elemen dan properti length mengembalikan jumlah elemen yang benar untuk setiap array.

2.3. Membandingkan Array dengan Array.equals

Sejauh ini kami hanya membandingkan array berdasarkan identitas objeknya. Di sisi lain, untuk memeriksa apakah dua larik sama dalam hal isinya, Java menyediakan metode statis Arrays.equals . Metode ini akan melakukan iterasi melalui array, per posisi secara paralel, dan menerapkan operator ==, untuk setiap pasangan elemen .

Mari buat dua array berbeda dengan literal String yang sama dengan urutan yang persis sama:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" };

Dan sekarang, mari kita tegaskan bahwa keduanya sama:

assertThat(Arrays.equals(planes1, planes2)).isTrue();

Jika kita mengubah urutan nilai dari array kedua:

String[] planes1 = new String[] { "A320", "B738", "A321", "A319", "B77W", "B737", "A333", "A332" }; String[] planes2 = new String[] { "B738", "A320", "A321", "A319", "B77W", "B737", "A333", "A332" }; 

Kami akan mendapatkan hasil yang berbeda:

assertThat(Arrays.equals(planes1, planes2)).isFalse();

2.4. Membandingkan Array dengan Array.deepEquals

Menggunakan operator == mudah jika kita menggunakan tipe sederhana di Java . Ini bisa menjadi tipe primitif atau string literal. Perbandingan antara array Object bisa lebih rumit. Alasan di balik ini sepenuhnya dijelaskan dalam artikel Arrays.deepEquals kami . Mari kita lihat contohnya.

Pertama, mari kita mulai dengan kelas Pesawat :

public class Plane { private final String name; private final String model; // getters and setters }

Dan, mari kita terapkan metode hashCode dan sama dengan :

@Override public boolean equals(Object o)  if (this == o) return true; if (o == null  @Override public int hashCode() { return Objects.hash(name, model); }

Kedua, mari buat array dua elemen berikut:

Plane[][] planes1 = new Plane[][] { new Plane[]{new Plane("Plane 1", "A320")}, new Plane[]{new Plane("Plane 2", "B738") }}; Plane[][] planes2 = new Plane[][] { new Plane[]{new Plane("Plane 1", "A320")}, new Plane[]{new Plane("Plane 2", "B738") }}; 

Sekarang mari kita lihat apakah itu benar, array yang sangat sama:

assertThat(Arrays.deepEquals(planes1, planes2)).isTrue();

Untuk memastikan bahwa perbandingan kita berfungsi seperti yang diharapkan, sekarang mari ubah urutan array terakhir kita:

Plane[][] planes1 = new Plane[][] { new Plane[]{new Plane("Plane 1", "A320")}, new Plane[]{new Plane("Plane 2", "B738") }}; Plane[][] planes2 = new Plane[][] { new Plane[]{new Plane("Plane 2", "B738")}, new Plane[]{new Plane("Plane 1", "A320") }};

Terakhir, mari kita uji apakah keduanya memang tidak sama lagi:

assertThat(Arrays.deepEquals(planes1, planes2)).isFalse();

2.5. Membandingkan Array dengan Urutan Elemen yang Berbeda

Untuk memeriksa apakah array sama, terlepas dari urutan elemennya, kita perlu menentukan apa yang membuat satu instance Pesawat kita unik . Untuk kasus kami, nama atau model yang berbeda sudah cukup untuk menentukan bahwa satu bidang berbeda dari yang lain. Kami telah menetapkan ini dengan telah menerapkan metode hashCode dan sama . Ini menyiratkan bahwa sebelum kita dapat membandingkan array kita, kita harus mengurutkannya. Untuk itu diperlukan Comparator :

Comparator planeComparator = (o1, o2) -> { if (o1.getName().equals(o2.getName())) { return o2.getModel().compareTo(o1.getModel()); } return o2.getName().compareTo(o1.getName()); };

In this Comparator, we're giving priority to the name. If the names are equal, we solve the ambiguity by looking at the model. We compare strings by using the compareTo method of type String.

We want to be able to find if arrays are equal regardless of the sorting order. To do that, let's now sort our arrays:

Arrays.sort(planes1[0], planeComparator); Arrays.sort(planes2[0], planeComparator);

And finally, let's test them:

assertThat(Arrays.deepEquals(planes1, planes2)).isTrue();

Having sorted the arrays in the same order first, we allow the deepEquals method to find if these two arrays are equal.

3. Conclusion

Dalam tutorial ini, kami telah melihat berbagai cara untuk membandingkan array. Kedua, kami melihat perbedaan antara membandingkan referensi dan nilai. Selain itu, kami telah melihat bagaimana kami dapat membandingkan array secara mendalam . Akhirnya, kami melihat perbedaan antara perbandingan normal dan perbandingan mendalam masing-masing menggunakan persamaan dan deepEquals .

Seperti biasa, kode sumber lengkap untuk contoh tersedia di GitHub.