Membandingkan Susunan di Jawa

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melihat cara yang berbeza untuk membandingkan tatasusunan di Java . Kami akan merangkumi kaedah konvensional, dan kami juga akan melihat beberapa contoh menggunakan ungkapan lambda .

2. Membandingkan Susunan

Kita akan membandingkan tatasusunan di Java, dan seperti yang kita tahu, ini adalah objek. Oleh itu, mari kita menyegarkan beberapa konsep asas:

  • Objek mempunyai rujukan dan nilai
  • Dua rujukan yang sama harus menunjukkan nilai yang sama
  • Dua nilai yang berbeza harus mempunyai rujukan yang berbeza
  • Dua nilai yang sama tidak semestinya mempunyai rujukan yang sama
  • Nilai primitif hanya dapat dibandingkan setiap nilai
  • String literal hanya dapat dibandingkan setiap nilai

2.1. Membandingkan Rujukan Objek

Sekiranya kita mempunyai dua rujukan yang menunjuk pada susunan yang sama, kita harus selalu mendapat hasil yang benar dalam perbandingan yang sama dengan operator == .

Mari lihat contoh:

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

Pertama, kami membuat pelbagai model pesawat yang dirujuk oleh pesawat1 . Kami kemudian membuat pesawat2 , yang merujuk pesawat1 . Dengan melakukan ini, kami membuat dua rujukan untuk array yang sama dalam memori . Oleh itu, ungkapan “planes1 == planes2” akan kembali benar .

Untuk tatasusunan, kaedah sama () sama dengan pengendali == . Jadi, planes1.equals (planes2) kembali benar kerana kedua-dua rujukan merujuk kepada objek yang sama. Secara umum, array1.eqauls (array2) akan kembali benar jika dan hanya jika ungkapan array1 == array2 ″ kembali benar .

Mari kita tegaskan jika kedua-dua rujukan itu sama:

assertThat(planes1).isSameAs(planes2);

Sekarang mari kita pastikan bahawa nilai yang dirujuk oleh satah1 sebenarnya sama dengan yang disebut oleh satah2 . Oleh itu, kita dapat mengubah susunan yang dirujuk oleh pesawat2, dan memeriksa apakah perubahan tersebut memberi kesan pada susunan yang dirujuk oleh satah1 :

planes2[0] = "747";

Untuk akhirnya melihat ini berfungsi, mari kita tegaskan:

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

Dengan ujian unit ini, kami dapat membandingkan dua tatasusunan dengan merujuk.

Namun, kami hanya membuktikan bahawa satu rujukan, setelah diberikan pada nilai yang lain, akan merujuk pada nilai yang sama.

Kami sekarang akan membuat dua tatasusunan yang berbeza 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" };

Oleh kerana mereka adalah objek yang berbeza, kita pasti tahu bahawa ia tidak sama. Oleh itu, kita dapat membandingkannya:

assertThat(planes1).isNotSameAs(planes2);

Kesimpulannya, dalam kes ini, kita mempunyai dua tatasusunan dalam memori yang mengandungi nilai String yang sama dalam urutan yang sama. Namun, bukan sahaja tatasusunan yang dirujuk berbeza dalam kandungan, tetapi rujukan itu sendiri juga berbeza.

2.2. Membandingkan Panjang Array

Panjang tatasusunan dapat dibandingkan tanpa mengira jenis elemennya, atau sama ada nilainya diisi atau tidak .

Mari buat dua tatasusunan:

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 tatasusunan yang berbeza dengan pelbagai jenis elemen. Dalam kumpulan data ini, kami mendaftarkan, sebagai contoh, berapa banyak kapal terbang dari setiap model yang disimpan di gudang. Sekarang mari kita jalankan ujian unit:

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

Dengan ini, kami telah membuktikan bahawa kedua-dua tatasusunan mempunyai lapan elemen dan bahawa sifat panjang mengembalikan bilangan elemen yang betul untuk setiap array.

2.3. Membandingkan Array dengan Arrays.equals

Setakat ini kami hanya membandingkan tatasusunan berdasarkan identiti objeknya. Sebaliknya, untuk memeriksa sama ada dua susunan sama dari segi kandungannya, Java menyediakan kaedah statik Array . Sama. Kaedah ini akan berulang melalui array, setiap kedudukan secara selari, dan menerapkan operator ==, untuk setiap pasangan elemen .

Mari buat dua tatasusunan yang berbeza dengan literal String yang sama mengikut urutan 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" };

Dan sekarang, mari kita tegaskan bahawa mereka sama:

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

Sekiranya kita mengubah susunan nilai 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 mendapat hasil yang berbeza:

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

2.4. Membandingkan Array dengan Arrays.deepEquals

Menggunakan operator == mudah jika kita menggunakan jenis mudah di Java . Ini mungkin jenis primitif atau literal String . Perbandingan antara tatasusunan Objek boleh menjadi lebih rumit. Sebab di sebalik ini dijelaskan sepenuhnya dalam artikel Arrays.deepEquals kami . Mari lihat contoh.

Pertama, mari kita mulakan dengan kelas Plane :

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

Dan, mari kita laksanakan kaedah 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 susunan 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, susunan yang sama:

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

Untuk memastikan bahawa perbandingan kami berfungsi seperti yang diharapkan, sekarang mari ubah urutan susunan terakhir kami:

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") }};

Akhir sekali, mari kita uji sama ada ia tidak sama lagi:

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

2.5. Membandingkan Susun atur dengan Susunan Unsur yang berbeza

Untuk memeriksa sama ada tatasusunan sama, tanpa mengira susunan elemen, kita perlu menentukan apa yang menjadikan satu contoh Pesawat kita unik . Untuk kes kami, nama atau model yang berbeza sudah cukup untuk menentukan bahawa satu pesawat berbeza dari yang lain. Kami telah menetapkan ini dengan telah melaksanakan kaedah hashCode dan sama . Ini menunjukkan bahawa sebelum kita dapat membandingkan tatasusunan kita, kita harus menyusunnya. Untuk itu, kita memerlukan Pembanding :

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, kita telah melihat pelbagai cara membandingkan tatasusunan. Kedua, kita melihat perbezaan antara membandingkan rujukan dan nilai. Di samping itu, kami telah melihat bagaimana kita dapat membandingkan tatasusunan dengan mendalam . Akhirnya, kami melihat perbezaan antara perbandingan normal dan perbandingan mendalam masing-masing menggunakan sama dan deepEquals .

Seperti biasa, kod sumber penuh untuk contoh boleh didapati di GitHub.