Confronto di array in Java

1. Panoramica

In questo tutorial, daremo uno sguardo a diversi modi per confrontare gli array in Java . Tratteremo i metodi convenzionali e vedremo anche alcuni esempi che utilizzano espressioni lambda .

2. Confronto di array

Confronteremo gli array in Java e, come sappiamo, questi sono oggetti. Pertanto, aggiorniamo alcuni concetti di base:

  • Gli oggetti hanno riferimenti e valori
  • Due riferimenti uguali dovrebbero puntare allo stesso valore
  • Due valori diversi dovrebbero avere riferimenti diversi
  • Due valori uguali non hanno necessariamente gli stessi riferimenti
  • I valori primitivi vengono confrontati solo per valore
  • I valori letterali stringa vengono confrontati solo per valore

2.1. Confronto dei riferimenti agli oggetti

Se abbiamo due riferimenti che puntano allo stesso array, dovremmo sempre ottenere un risultato vero in un confronto di uguale con l' operatore == .

Diamo un'occhiata a un esempio:

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

Per prima cosa, abbiamo creato una serie di modelli di piani referenziati da planes1 . Quindi creiamo planes2 , che fa riferimento a planes1 . In questo modo, creiamo due riferimenti allo stesso array in memoria . Pertanto, l' espressione "planes1 == planes2" restituirà true .

Per gli array, il metodo equals () è lo stesso dell'operatore == . Quindi, planes1.equals (planes2) restituisce true perché entrambi i riferimenti si riferiscono allo stesso oggetto. In generale, array1.eqauls (array2) restituirà true se e solo se l'espressione " array1 == array2 ″ restituisce true .

Asseriamo se i due riferimenti sono gli stessi:

assertThat(planes1).isSameAs(planes2);

Assicuriamoci ora che i valori referenziati da planes1 siano effettivamente gli stessi di quelli referenziati da planes2 . Pertanto, possiamo modificare l'array a cui fa riferimento planes2 e verificare se le modifiche hanno alcun impatto sull'array a cui fa riferimento planes1 :

planes2[0] = "747";

Per vedere finalmente che funziona, facciamo le nostre affermazioni:

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

Con questo test unitario, siamo stati in grado di confrontare due array per riferimento.

Tuttavia, abbiamo solo dimostrato che un riferimento, una volta assegnato al valore di un altro, farà riferimento allo stesso valore.

Creeremo ora due diversi array con gli stessi valori:

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

Poiché sono oggetti diversi, sappiamo per certo che non sono la stessa cosa. Possiamo, quindi, confrontarli:

assertThat(planes1).isNotSameAs(planes2);

Per riassumere, in questo caso, abbiamo due array in memoria che contengono gli stessi valori String esattamente nello stesso ordine. Tuttavia, non solo gli array di riferimento sono diversi nel contenuto, ma anche i riferimenti stessi sono diversi.

2.2. Confronto delle lunghezze degli array

La lunghezza degli array può essere confrontata indipendentemente dai loro tipi di elemento o dal fatto che i loro valori siano inseriti o meno .

Creiamo due 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 };

Questi sono due diversi array con diversi tipi di elementi. In questo set di dati, stiamo registrando, ad esempio, quanti aeroplani di ogni modello sono immagazzinati nel magazzino. Eseguiamo ora unit test su di essi:

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

Con questo, abbiamo dimostrato che entrambi gli array hanno otto elementi e che la proprietà length restituisce il numero corretto di elementi per ogni array.

2.3. Confronto di array con Arrays.equals

Finora abbiamo confrontato solo gli array in base alle loro identità di oggetto. D'altra parte, per verificare se due array sono uguali in termini di contenuto, Java fornisce il metodo statico Arrays.equals . Questo metodo itererà attraverso gli array, per posizione in parallelo, e applicherà l'operatore ==, per ogni coppia di elementi .

Creiamo due array diversi con le stesse stringhe letterali esattamente nello stesso ordine:

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

E ora, affermiamo che sono uguali:

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

Se cambiamo l'ordine dei valori del secondo array:

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

Otterremo un risultato diverso:

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

2.4. Confronto di array con Arrays.deepEquals

Usare l' operatore == è facile se usiamo tipi semplici in Java . Questi potrebbero essere tipi primitivi o stringhe letterali. Un confronto tra array di oggetti può essere più complicato. La ragione di ciò è completamente spiegata nel nostro articolo Arrays.deepEquals . Vediamo un esempio.

Innanzitutto, iniziamo con una classe Plane :

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

E implementiamo i metodi hashCode ed equals :

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

In secondo luogo, creiamo i seguenti array a due elementi:

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

Vediamo ora se sono array veri, profondamente uguali:

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

Per assicurarci che il nostro confronto funzioni come previsto, cambiamo ora l'ordine del nostro ultimo array:

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

Infine, testiamo se effettivamente non sono più uguali:

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

2.5. Confronto di array con diversi ordini di elementi

Per verificare se gli array sono uguali, indipendentemente dall'ordine degli elementi, è necessario definire cosa rende un'istanza nostro piano unico . Nel nostro caso, un nome o un modello diverso è sufficiente per determinare che un piano è diverso da un altro. Lo abbiamo stabilito avendo già implementato entrambi i metodi hashCode ed equals . Ciò implica che prima di poter confrontare i nostri array, dovremmo ordinarli. Per questo, abbiamo bisogno di un comparatore :

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

In questo tutorial, abbiamo visto diversi modi di confrontare gli array. In secondo luogo, abbiamo visto la differenza tra il confronto di riferimenti e valori. Inoltre, abbiamo esaminato come possiamo confrontare gli array in modo approfondito . Infine, abbiamo visto la differenza tra un confronto normale e un confronto profondo utilizzando rispettivamente uguale e deepEquals .

Come sempre, il codice sorgente completo per gli esempi è disponibile su GitHub.