Java Language
Array
Ricerca…
introduzione
Le matrici consentono la memorizzazione e il recupero di una quantità arbitraria di valori. Sono analoghi ai vettori in matematica. Le matrici di array sono analoghe alle matrici e agiscono come array multidimensionali. Le matrici possono memorizzare qualsiasi tipo di dati: primitive come int
o tipi di riferimento come Object
.
Sintassi
-
ArrayType[] myArray;
// Dichiarare gli array -
ArrayType myArray[];
// Un'altra sintassi valida (meno comunemente usata e scoraggiata) -
ArrayType[][][] myArray;
// Dichiarazione di matrici frastagliate multidimensionali (ripeti [] s) -
ArrayType myVar = myArray[index];
// Accesso (lettura) elemento all'indice -
myArray[index] = value;
// valore Assign alla posizioneindex
di matrice -
ArrayType[] myArray = new ArrayType[arrayLength];
// Sintassi di inizializzazione dell'array -
int[] ints = {1, 2, 3};
// Sintassi di inizializzazione dell'array con i valori forniti, la lunghezza viene dedotta dal numero di valori forniti: {[valore1 [, valore2] *]} -
new int[]{4, -5, 6} // Can be used as argument, without a local variable
-
int[] ints = new int[3]; // same as {0, 0, 0}
-
int[][] ints = {{1, 2}, {3}, null};
// Inizializzazione array multidimensionale. int [] estende Object (e così anyType []) quindi null è un valore valido.
Parametri
Parametro | Dettagli |
---|---|
ArrayType | Tipo della matrice. Questo può essere primitivo ( int , long , byte ) o Objects ( String , MyObject , ecc.). |
indice | L'indice si riferisce alla posizione di un determinato oggetto in una matrice. |
lunghezza | Ogni array, una volta creato, ha bisogno di una lunghezza specificata. Questo viene fatto quando si crea un array vuoto ( new int[3] ) o implicito quando si specificano valori ( {1, 2, 3} ). |
Creazione e inizializzazione di matrici
Casi di base
int[] numbers1 = new int[3]; // Array for 3 int values, default value is 0
int[] numbers2 = { 1, 2, 3 }; // Array literal of 3 int values
int[] numbers3 = new int[] { 1, 2, 3 }; // Array of 3 int values initialized
int[][] numbers4 = { { 1, 2 }, { 3, 4, 5 } }; // Jagged array literal
int[][] numbers5 = new int[5][]; // Jagged array, one dimension 5 long
int[][] numbers6 = new int[5][4]; // Multidimensional array: 5x4
Le matrici possono essere create usando qualsiasi tipo di primitivo o di riferimento.
float[] boats = new float[5]; // Array of five 32-bit floating point numbers.
double[] header = new double[] { 4.56, 332.267, 7.0, 0.3367, 10.0 };
// Array of five 64-bit floating point numbers.
String[] theory = new String[] { "a", "b", "c" };
// Array of three strings (reference type).
Object[] dArt = new Object[] { new Object(), "We love Stack Overflow.", new Integer(3) };
// Array of three Objects (reference type).
Per l'ultimo esempio, si noti che i sottotipi del tipo di array dichiarato sono consentiti nell'array.
Le matrici per i tipi definiti dall'utente possono anche essere costruite in modo simile ai tipi primitivi
UserDefinedClass[] udType = new UserDefinedClass[5];
Array, raccolte e flussi
// Parameters require objects, not primitives
// Auto-boxing happening for int 127 here
Integer[] initial = { 127, Integer.valueOf( 42 ) };
List<Integer> toList = Arrays.asList( initial ); // Fixed size!
// Note: Works with all collections
Integer[] fromCollection = toList.toArray( new Integer[toList.size()] );
//Java doesn't allow you to create an array of a parameterized type
List<String>[] list = new ArrayList<String>[2]; // Compilation error!
// Streams - JDK 8+
Stream<Integer> toStream = Arrays.stream( initial );
Integer[] fromStream = toStream.toArray( Integer[]::new );
Intro
Una matrice è una struttura di dati che contiene un numero fisso di valori primitivi o riferimenti a istanze di oggetti.
Ogni elemento in un array è chiamato un elemento e ogni elemento è accessibile tramite il suo indice numerico. La lunghezza di un array viene stabilita al momento della creazione dell'array:
int size = 42;
int[] array = new int[size];
La dimensione di un array è fissata al runtime quando inizializzata. Non può essere modificato dopo l'inizializzazione. Se la dimensione deve essere mutabile in fase di esecuzione, deve essere utilizzata una classe Collection
come ArrayList
. ArrayList
archivia elementi in un array e supporta il ridimensionamento allocando un nuovo array e copiando gli elementi dal vecchio array.
Se l'array è di tipo primitivo, es
int[] array1 = { 1,2,3 };
int[] array2 = new int[10];
i valori sono memorizzati nella matrice stessa. In assenza di un inizializzatore (come in array2
sopra), il valore predefinito assegnato a ciascun elemento è 0
(zero).
Se il tipo di matrice è un riferimento a un oggetto, come in
SomeClassOrInterface[] array = new SomeClassOrInterface[10];
quindi la matrice contiene riferimenti a oggetti di tipo SomeClassOrInterface
. Tali riferimenti possono fare riferimento a un'istanza di SomeClassOrInterface
o qualsiasi sottoclasse (per le classi) o alla classe di implementazione (per le interfacce) di SomeClassOrInterface
. Se la dichiarazione dell'array non ha inizializzatore, il valore predefinito di null
viene assegnato a ciascun elemento.
Poiché tutti gli array sono int
-indexed, la dimensione di un array deve essere specificata da un int
. La dimensione dell'array non può essere specificata come una long
:
long size = 23L;
int[] array = new int[size]; // Compile-time error:
// incompatible types: possible lossy conversion from
// long to int
Le matrici utilizzano un sistema di indice a base zero , il che significa che l'indicizzazione inizia da 0
e termina a length - 1
.
Ad esempio, l'immagine seguente rappresenta una matrice con dimensione 10
. Qui, il primo elemento si trova nell'indice 0
e l'ultimo elemento è nell'indice 9
, invece del primo elemento nell'indice 1
e nell'ultimo elemento nell'indice 10
(vedi figura sotto).
Gli accessi agli elementi degli array vengono eseguiti in tempo costante . Ciò significa che l'accesso al primo elemento dell'array ha lo stesso costo (nel tempo) dell'accesso al secondo elemento, al terzo elemento e così via.
Java offre diversi modi per definire e inizializzare gli array, comprese le notazioni letterali e del costruttore . Quando si dichiarano gli array usando il new Type[length]
costruttore new Type[length]
, ogni elemento sarà inizializzato con i seguenti valori predefiniti:
-
0
per tipi numerici primitivi :byte
,short
,int
,long
,float
edouble
. -
'\u0000'
(carattere null) per il tipo dichar
. -
false
per il tipoboolean
. -
null
per i tipi di riferimento .
Creazione e inizializzazione di matrici di tipi primitivi
int[] array1 = new int[] { 1, 2, 3 }; // Create an array with new operator and
// array initializer.
int[] array2 = { 1, 2, 3 }; // Shortcut syntax with array initializer.
int[] array3 = new int[3]; // Equivalent to { 0, 0, 0 }
int[] array4 = null; // The array itself is an object, so it
// can be set as null.
Quando si dichiara un array, []
apparirà come parte del tipo all'inizio della dichiarazione (dopo il nome del tipo), o come parte del dichiaratore per una particolare variabile (dopo il nome della variabile), o entrambi:
int array5[]; /* equivalent to */ int[] array5;
int a, b[], c[][]; /* equivalent to */ int a; int[] b; int[][] c;
int[] a, b[]; /* equivalent to */ int[] a; int[][] b;
int a, []b, c[][]; /* Compilation Error, because [] is not part of the type at beginning
of the declaration, rather it is before 'b'. */
// The same rules apply when declaring a method that returns an array:
int foo()[] { ... } /* equivalent to */ int[] foo() { ... }
Nell'esempio seguente, entrambe le dichiarazioni sono corrette e possono essere compilate ed eseguite senza problemi. Tuttavia, sia la convenzione di codifica Java che la Guida allo stile di Java di Google scoraggiano il modulo con parentesi dopo il nome della variabile: le parentesi identificano il tipo di matrice e dovrebbero apparire con la designazione del tipo . Lo stesso dovrebbe essere usato per le firme di ritorno del metodo.
float array[]; /* and */ int foo()[] { ... } /* are discouraged */
float[] array; /* and */ int[] foo() { ... } /* are encouraged */
Il tipo scoraggiato è pensato per accogliere gli utenti in transizione C , che hanno familiarità con la sintassi per C che ha le parentesi dopo il nome della variabile.
In Java, è possibile avere array di dimensione 0
:
int[] array = new int[0]; // Compiles and runs fine.
int[] array2 = {}; // Equivalent syntax.
Tuttavia, poiché si tratta di un array vuoto, non è possibile leggere da esso né assegnargli elementi:
array[0] = 1; // Throws java.lang.ArrayIndexOutOfBoundsException.
int i = array2[0]; // Also throws ArrayIndexOutOfBoundsException.
Tali array vuoti sono in genere utili come valori di ritorno, in modo che il codice chiamante debba preoccuparsi solo di gestire un array, piuttosto che un potenziale valore null
che può portare a una NullPointerException
.
La lunghezza di un array deve essere un numero intero non negativo:
int[] array = new int[-1]; // Throws java.lang.NegativeArraySizeException
La dimensione dell'array può essere determinata utilizzando un campo finale pubblico chiamato length
:
System.out.println(array.length); // Prints 0 in this case.
Nota : array.length
restituisce la dimensione effettiva dell'array e non il numero di elementi dell'array a cui è stato assegnato un valore, diversamente da ArrayList.size()
che restituisce il numero di elementi dell'array a cui è stato assegnato un valore.
Creazione e inizializzazione di array multidimensionali
Il modo più semplice per creare un array multidimensionale è il seguente:
int[][] a = new int[2][3];
Creerà due int
arriys a[0]
tre lunghezze: a[0]
e a[1]
. Questo è molto simile alla classica inizializzazione in stile C degli array rettangolari multidimensionali.
Puoi creare e inizializzare allo stesso tempo:
int[][] a = { {1, 2}, {3, 4}, {5, 6} };
A differenza di C , in cui sono supportati solo array rettangolari multidimensionali, gli array interni non devono necessariamente avere la stessa lunghezza o anche essere definiti:
int[][] a = { {1}, {2, 3}, null };
Qui, a[0]
è un array int
lunghezza singola, mentre a[1]
è un array int
due lunghezze e a[2]
è null
. Array come questo sono chiamati array frastagliati o array frastagliati , cioè sono matrici di array. Gli array multidimensionali in Java sono implementati come array di matrici, cioè array[i][j][k]
è equivalente a ((array[i])[j])[k]
. A differenza di C # , l' array[i,j]
sintassi array[i,j]
non è supportato in Java.
Rappresentazione di array multidimensionali in Java
Creazione e inizializzazione di matrici di tipi di riferimento
String[] array6 = new String[] { "Laurel", "Hardy" }; // Create an array with new
// operator and array initializer.
String[] array7 = { "Laurel", "Hardy" }; // Shortcut syntax with array
// initializer.
String[] array8 = new String[3]; // { null, null, null }
String[] array9 = null; // null
Oltre ai letterali e alle primitive String
mostrati sopra, la sintassi di scelta rapida per l'inizializzazione dell'array funziona anche con tipi di Object
canonici:
Object[] array10 = { new Object(), new Object() };
Poiché gli array sono covarianti, un array di tipi di riferimento può essere inizializzato come array di una sottoclasse, sebbene venga generata ArrayStoreException
se si tenta di impostare un elemento su qualcosa di diverso da una String
:
Object[] array11 = new String[] { "foo", "bar", "baz" };
array11[1] = "qux"; // fine
array11[1] = new StringBuilder(); // throws ArrayStoreException
La sintassi di scelta rapida non può essere utilizzata per questo perché la sintassi di scelta rapida avrebbe un tipo implicito di Object[]
.
Un array può essere inizializzato con zero elementi utilizzando String[] emptyArray = new String[0]
. Ad esempio, una matrice con lunghezza zero come questa viene utilizzata per la creazione di una Array
da una Collection
quando il metodo richiede il tipo di esecuzione di un oggetto.
In entrambi i tipi primitivi e di riferimento, un'inizializzazione di array vuota (ad esempio String[] array8 = new String[3]
) inizializzerà la matrice con il valore predefinito per ogni tipo di dati .
Creazione e inizializzazione di array di tipi generici
Nelle classi generiche, le matrici di tipi generici non possono essere inizializzate in questo modo a causa della cancellazione del tipo :
public class MyGenericClass<T> {
private T[] a;
public MyGenericClass() {
a = new T[5]; // Compile time error: generic array creation
}
}
Invece, possono essere creati usando uno dei seguenti metodi: (nota che questi genereranno avvisi non controllati)
Creando una matrice
Object
e convertendola nel tipo generico:a = (T[]) new Object[5];
Questo è il metodo più semplice, ma poiché l'array sottostante è ancora di tipo
Object[]
, questo metodo non fornisce sicurezza di tipo. Pertanto, questo metodo di creazione di un array viene utilizzato al meglio solo all'interno della classe generica, non è esposto pubblicamente.Usando
Array.newInstance
con un parametro di classe:public MyGenericClass(Class<T> clazz) { a = (T[]) Array.newInstance(clazz, 5); }
Qui la classe di
T
deve essere esplicitamente passata al costruttore. Il tipo di ritorno diArray.newInstance
è sempreObject
. Tuttavia, questo metodo è più sicuro perché l'array appena creato è sempre di tipoT[]
, e quindi può essere tranquillamente esternalizzato.
Riempimento di un array dopo l'inizializzazione
Arrays.fill()
può essere utilizzato per riempire una matrice con lo stesso valore dopo l'inizializzazione:
Arrays.fill(array8, "abc"); // { "abc", "abc", "abc" }
fill()
può anche assegnare un valore a ciascun elemento dell'intervallo specificato dell'array:
Arrays.fill(array8, 1, 2, "aaa"); // Placing "aaa" from index 1 to 2.
Dalla versione 8 di Java, è possibile utilizzare il metodo setAll
e il relativo parallelSetAll
Concurrent
per impostare ogni elemento di un array su valori generati. Questi metodi sono passati a una funzione generatore che accetta un indice e restituisce il valore desiderato per quella posizione.
L'esempio seguente crea un array intero e imposta tutti i suoi elementi sul rispettivo valore di indice:
int[] array = new int[5];
Arrays.setAll(array, i -> i); // The array becomes { 0, 1, 2, 3, 4 }.
Dichiarazione separata e inizializzazione degli array
Il valore di un indice per un elemento dell'array deve essere un numero intero (0, 1, 2, 3, 4, ...) e inferiore alla lunghezza dell'array (gli indici sono a base zero). Altrimenti verrà lanciata una ArrayIndexOutOfBoundsException :
int[] array9; // Array declaration - uninitialized
array9 = new int[3]; // Initialize array - { 0, 0, 0 }
array9[0] = 10; // Set index 0 value - { 10, 0, 0 }
array9[1] = 20; // Set index 1 value - { 10, 20, 0 }
array9[2] = 30; // Set index 2 value - { 10, 20, 30 }
Gli array non possono essere reinizializzati con la sintassi di scelta rapida di array initializer
Non è possibile inizializzare nuovamente un array tramite una sintassi di scelta rapida con un inizializzatore di array poiché un inizializzatore di array può essere specificato solo in una dichiarazione di campo o in una dichiarazione di variabile locale o come parte di un'espressione di creazione di matrice.
Tuttavia, è possibile creare un nuovo array e assegnarlo alla variabile utilizzata per fare riferimento al vecchio array. Mentre ciò comporta che l'array a cui fa riferimento tale variabile venga reinizializzato, il contenuto della variabile è un array completamente nuovo. Per fare ciò, il new
operatore può essere utilizzato con un inizializzatore di array e assegnato alla variabile array:
// First initialization of array
int[] array = new int[] { 1, 2, 3 };
// Prints "1 2 3 ".
for (int i : array) {
System.out.print(i + " ");
}
// Re-initializes array to a new int[] array.
array = new int[] { 4, 5, 6 };
// Prints "4 5 6 ".
for (int i : array) {
System.out.print(i + " ");
}
array = { 1, 2, 3, 4 }; // Compile-time error! Can't re-initialize an array via shortcut
// syntax with array initializer.
Creazione di una matrice da una raccolta
Due metodi in java.util.Collection
creano una matrice da una raccolta:
Object[] toArray()
può essere utilizzato come segue:
Set<String> set = new HashSet<String>();
set.add("red");
set.add("blue");
// although set is a Set<String>, toArray() returns an Object[] not a String[]
Object[] objectArray = set.toArray();
<T> T[] toArray(T[] a)
può essere utilizzato come segue:
Set<String> set = new HashSet<String>();
set.add("red");
set.add("blue");
// The array does not need to be created up front with the correct size.
// Only the array type matters. (If the size is wrong, a new array will
// be created with the same type.)
String[] stringArray = set.toArray(new String[0]);
// If you supply an array of the same size as collection or bigger, it
// will be populated with collection values and returned (new array
// won't be allocated)
String[] stringArray2 = set.toArray(new String[set.size()]);
La differenza tra loro è molto più che avere risultati non tipizzati rispetto a quelli digitati. Anche le loro prestazioni possono differire (per ulteriori dettagli, leggi questa sezione sull'analisi delle prestazioni ):
-
Object[] toArray()
usaarraycopy
vettorizzato, che è molto più veloce rispetto alarraycopy
controllo delarraycopy
utilizzato inT[] toArray(T[] a)
. -
T[] toArray(new T[non-zero-size])
bisogno di azzerare l'array durante il runtime, mentreT[] toArray(new T[0])
no. Tale evitamento fa chiamare quest'ultima più veloce della prima. Analisi dettagliata qui: Arrays of Wisdom of the Ancients .
A partire da Java SE 8+, in cui è stato introdotto il concetto di Stream
, è possibile utilizzare il Stream
prodotto dalla raccolta per creare un nuovo array utilizzando il metodo Stream.toArray
.
String[] strings = list.stream().toArray(String[]::new);
Esempi presi da due risposte ( 1 , 2 ) alla conversione di 'ArrayList in' String [] 'in Java su Stack Overflow.
Matrici a una stringa
Da Java 1.5 è possibile ottenere una rappresentazione String
dei contenuti della matrice specificata senza iterare su ogni elemento. Basta usare Arrays.toString(Object[])
o Arrays.deepToString(Object[])
per gli array multidimental:
int[] arr = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5]
int[][] arr = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(Arrays.deepToString(arr)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Arrays.toString()
metodo Arrays.toString()
utilizza il metodo Object.toString()
per produrre valori di String
di ogni elemento dell'array, oltre all'array di tipo primitivo, può essere utilizzato per tutti i tipi di matrici. Per esempio:
public class Cat { /* implicitly extends Object */
@Override
public String toString() {
return "CAT!";
}
}
Cat[] arr = { new Cat(), new Cat() };
System.out.println(Arrays.toString(arr)); // [CAT!, CAT!]
Se non esiste alcun toString()
override per la classe, verrà utilizzato il toString()
ereditato da Object
. Di solito l'output non è molto utile, ad esempio:
public class Dog {
/* implicitly extends Object */
}
Dog[] arr = { new Dog() };
System.out.println(Arrays.toString(arr)); // [Dog@17ed40e0]
Creare una lista da una matrice
Il metodo Arrays.asList()
può essere usato per restituire una List
dimensione fissa contenente gli elementi dell'array dato. L' List
risultante avrà lo stesso tipo di parametro del tipo base dell'array.
String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = Arrays.asList(stringArray);
Nota : questo elenco è supportato da una vista della matrice originale, il che significa che qualsiasi modifica alla lista cambierà la matrice e viceversa. Tuttavia, le modifiche alla lista che cambierebbero le sue dimensioni (e quindi la lunghezza dell'array) genereranno un'eccezione.
Per creare una copia dell'elenco, utilizzare il costruttore di java.util.ArrayList
che java.util.ArrayList
una Collection
come argomento:
String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = new ArrayList<String>(Arrays.asList(stringArray));
In Java SE 7 e versioni successive, è possibile utilizzare una coppia di parentesi angolari <>
(set vuoto di argomenti tipo), che si chiama Diamond . Il compilatore può determinare gli argomenti di tipo dal contesto. Ciò significa che le informazioni sul tipo possono essere omesse quando si chiama il costruttore di ArrayList
e verranno dedotte automaticamente durante la compilazione. Questo è chiamato tipo Inferenza che fa parte di Java Generics .
// Using Arrays.asList()
String[] stringArray = {"foo", "bar", "baz"};
List<String> stringList = new ArrayList<>(Arrays.asList(stringArray));
// Using ArrayList.addAll()
String[] stringArray = {"foo", "bar", "baz"};
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList(stringArray));
// Using Collections.addAll()
String[] stringArray = {"foo", "bar", "baz"};
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, stringArray);
Un punto degno di nota sul diamante è che non può essere utilizzato con le classi anonime .
// Using Streams
int[] ints = {1, 2, 3};
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());
String[] stringArray = {"foo", "bar", "baz"};
List<Object> list = Arrays.stream(stringArray).collect(Collectors.toList());
Note importanti relative all'uso del metodo Arrays.asList ()
Questo metodo restituisce
List
, che è un'istanza diArrays$ArrayList
(classe interna statica diArrays
) e nonjava.util.ArrayList
. L'List
risultante è di dimensioni fisse. Ciò significa che l'aggiunta o la rimozione di elementi non è supportata e genererà unUnsupportedOperationException
:stringList.add("something"); // throws java.lang.UnsupportedOperationException
Un nuovo
List
può essere creato passando unList
supportato da array al costruttore di una nuovaList
. Ciò crea una nuova copia dei dati, che ha dimensioni variabili e che non è supportata dall'array originale:List<String> modifiableList = new ArrayList<>(Arrays.asList("foo", "bar"));
Chiamando
<T> List<T> asList(T... a)
su un array primitivo, ad esempio unint[]
, verrà generato unList<int[]>
cui unico elemento è l'array primitivo di origine anziché gli elementi effettivi dell'array sorgente.La ragione di questo comportamento è che i tipi primitivi non possono essere usati al posto dei parametri di tipo generico, quindi l'intero array primitivo sostituisce il parametro di tipo generico in questo caso. Per convertire una matrice primitiva in una
List
, convertire innanzitutto la matrice primitiva in una matrice del tipo di wrapper corrispondente (ad esempio, chiamareArrays.asList
su un numeroInteger[]
anziché su unint[]
).Pertanto, questo verrà stampato
false
:int[] arr = {1, 2, 3}; // primitive array of int System.out.println(Arrays.asList(arr).contains(1));
D'altra parte, questo verrà stampato
true
:Integer[] arr = {1, 2, 3}; // object array of Integer (wrapper for int) System.out.println(Arrays.asList(arr).contains(1));
Anche questo verrà stampato
true
, poiché l'array verrà interpretato come unInteger[]
):System.out.println(Arrays.asList(1,2,3).contains(1));
Matrici multidimensionali e frastagliate
È possibile definire una matrice con più di una dimensione. Invece di accedere con un singolo indice, è possibile accedere a un array multidimensionale specificando un indice per ogni dimensione.
La dichiarazione dell'array multidimensionale può essere eseguita aggiungendo []
per ogni dimensione a una normale declinazione dell'array. Ad esempio, per creare un array int
bidimensionale, aggiungi un altro insieme di parentesi alla dichiarazione, ad esempio int[][]
. Questo continua per gli array 3-dimensionale ( int[][][]
) e così via.
Per definire una matrice bidimensionale con tre righe e tre colonne:
int rows = 3;
int columns = 3;
int[][] table = new int[rows][columns];
L'array può essere indicizzato e assegnare valori ad esso con questo costrutto. Si noti che i valori non assegnati sono i valori predefiniti per il tipo di un array, in questo caso 0
per int
.
table[0][0] = 0;
table[0][1] = 1;
table[0][2] = 2;
È anche possibile creare un'istanza di una dimensione alla volta e persino creare array non rettangolari. Questi sono più comunemente indicati come matrici frastagliate .
int[][] nonRect = new int[4][];
È importante notare che, sebbene sia possibile definire qualsiasi dimensione della matrice seghettata, è necessario definire il livello precedente.
// valid
String[][] employeeGraph = new String[30][];
// invalid
int[][] unshapenMatrix = new int[][10];
// also invalid
int[][][] misshapenGrid = new int[100][][10];
Come gli array multidimensionali sono rappresentati in Java
Fonte immagine: http://math.hws.edu/eck/cs124/javanotes3/c8/s5.html
Intializzazione letterale a matrice seghettata
Array multidimensionali e matrici frastagliate possono anche essere inizializzati con un'espressione letterale. Quanto segue dichiara e popola un array int
2x3:
int[][] table = {
{1, 2, 3},
{4, 5, 6}
};
Nota : i sottotitoli seghettati potrebbero anche essere null
. Ad esempio, il seguente codice dichiara e popola un array int
bidimensionale il cui primo sottoarray è null
, il secondo sottoarray è di lunghezza zero, il terzo sottoarray è di una lunghezza e l'ultimo sottoarray è un array di due lunghezze:
int[][] table = {
null,
{},
{1},
{1,2}
};
Per array multidimensionali è possibile estrarre array di dimensioni di livello inferiore dai loro indici:
int[][][] arr = new int[3][3][3];
int[][] arr1 = arr[0]; // get first 3x3-dimensional array from arr
int[] arr2 = arr1[0]; // get first 3-dimensional array from arr1
int[] arr3 = arr[0]; // error: cannot convert from int[][] to int[]
Indice della Matrice Fuori Dai Limiti d'Eccezione
L' ArrayIndexOutOfBoundsException
viene generata quando si accede a un indice non esistente di un array.
Le matrici sono indicizzate su base zero, quindi l'indice del primo elemento è 0
e l'indice dell'ultimo elemento è la capacità dell'array meno 1
(cioè array.length - 1
).
Pertanto, qualsiasi richiesta per un elemento dell'array dall'indice i
deve soddisfare la condizione 0 <= i < array.length
, altrimenti verrà ArrayIndexOutOfBoundsException
l' ArrayIndexOutOfBoundsException
.
Il seguente codice è un semplice esempio in cui viene lanciata una ArrayIndexOutOfBoundsException
.
String[] people = new String[] { "Carol", "Andy" };
// An array will be created:
// people[0]: "Carol"
// people[1]: "Andy"
// Notice: no item on index 2. Trying to access it triggers the exception:
System.out.println(people[2]); // throws an ArrayIndexOutOfBoundsException.
Produzione:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at your.package.path.method(YourClass.java:15)
Si noti che l'indice illegale a cui si accede è anche incluso nell'eccezione ( 2
nell'esempio); questa informazione potrebbe essere utile per trovare la causa dell'eccezione.
Per evitare ciò, è sufficiente verificare che l'indice sia entro i limiti dell'array:
int index = 2;
if (index >= 0 && index < people.length) {
System.out.println(people[index]);
}
Ottenere la lunghezza di una matrice
Le matrici sono oggetti che forniscono spazio per memorizzare fino alla sua dimensione di elementi di tipo specificato. La dimensione di un array non può essere modificata dopo la creazione dell'array.
int[] arr1 = new int[0];
int[] arr2 = new int[2];
int[] arr3 = new int[]{1, 2, 3, 4};
int[] arr4 = {1, 2, 3, 4, 5, 6, 7};
int len1 = arr1.length; // 0
int len2 = arr2.length; // 2
int len3 = arr3.length; // 4
int len4 = arr4.length; // 7
Il campo length
in un array memorizza la dimensione di un array. È un campo final
e non può essere modificato.
Questo codice mostra la differenza tra la length
di un array e la quantità di oggetti che un array memorizza.
public static void main(String[] args) {
Integer arr[] = new Integer[] {1,2,3,null,5,null,7,null,null,null,11,null,13};
int arrayLength = arr.length;
int nonEmptyElementsCount = 0;
for (int i=0; i<arrayLength; i++) {
Integer arrElt = arr[i];
if (arrElt != null) {
nonEmptyElementsCount++;
}
}
System.out.println("Array 'arr' has a length of "+arrayLength+"\n"
+ "and it contains "+nonEmptyElementsCount+" non-empty values");
}
Risultato:
Array 'arr' has a length of 13
and it contains 7 non-empty values
Confronto tra array per l'uguaglianza
I tipi di matrice ereditano le loro implementazioni equals()
(e hashCode()
) da java.lang.Object , quindi equals()
restituisce true solo quando si confronta con lo stesso identico oggetto array. Per confrontare gli array per l'uguaglianza in base ai loro valori, utilizzare java.util.Arrays.equals
, che è sovraccarico per tutti i tipi di array.
int[] a = new int[]{1, 2, 3};
int[] b = new int[]{1, 2, 3};
System.out.println(a.equals(b)); //prints "false" because a and b refer to different objects
System.out.println(Arrays.equals(a, b)); //prints "true" because the elements of a and b have the same values
Quando il tipo di elemento è un tipo di riferimento, Arrays.equals()
chiama equals()
sugli elementi dell'array per determinare l'uguaglianza. In particolare, se il tipo di elemento è esso stesso un tipo di matrice, verrà utilizzato il confronto dell'identità. Per confrontare gli array multidimensionali per l'uguaglianza, utilizzare invece Arrays.deepEquals()
come di seguito:
int a[] = { 1, 2, 3 };
int b[] = { 1, 2, 3 };
Object[] aObject = { a }; // aObject contains one element
Object[] bObject = { b }; // bObject contains one element
System.out.println(Arrays.equals(aObject, bObject)); // false
System.out.println(Arrays.deepEquals(aObject, bObject));// true
Poiché gli insiemi e le mappe utilizzano equals()
e hashCode()
, gli array generalmente non sono utili come elementi impostati o chiavi della mappa. Indirizzali in una classe helper che implementa equals()
e hashCode()
in termini di elementi dell'array, o convertili in istanze di List
e memorizzi gli elenchi.
Array per lo streaming
Conversione di una matrice di oggetti su Stream
:
String[] arr = new String[] {"str1", "str2", "str3"};
Stream<String> stream = Arrays.stream(arr);
La conversione di una matrice di primitivi in Stream
utilizzando Arrays.stream()
trasformerà l'array in una specializzazione primitiva di Stream:
int[] intArr = {1, 2, 3};
IntStream intStream = Arrays.stream(intArr);
È inoltre possibile limitare il Stream
a un intervallo di elementi nell'array. L'indice iniziale è inclusivo e l'indice finale è esclusivo:
int[] values = {1, 2, 3, 4};
IntStream intStream = Arrays.stream(values, 2, 4);
Un metodo simile a Arrays.stream()
appare nella classe Stream
: Stream.of()
. La differenza è che Stream.of()
usa un parametro varargs, quindi puoi scrivere qualcosa come:
Stream<Integer> intStream = Stream.of(1, 2, 3);
Stream<String> stringStream = Stream.of("1", "2", "3");
Stream<Double> doubleStream = Stream.of(new Double[]{1.0, 2.0});
Iterare su array
È possibile eseguire iterazioni su array utilizzando il ciclo for enhanced (aka foreach) o utilizzando gli indici di array:
int[] array = new int[10];
// using indices: read and write
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
// extended for: read only
for (int e : array) {
System.out.println(e);
}
Vale la pena notare che non esiste un modo diretto per usare un Iterator su una matrice, ma attraverso la libreria di Array può essere facilmente convertito in una lista per ottenere un oggetto Iterable
.
Per gli array in box usa Arrays.asList :
Integer[] boxed = {1, 2, 3};
Iterable<Integer> boxedIt = Arrays.asList(boxed); // list-backed iterable
Iterator<Integer> fromBoxed1 = boxedIt.iterator();
Per gli array primitivi (usando java 8) utilizzare gli stream (in particolare in questo esempio: Arrays.stream -> IntStream ):
int[] primitives = {1, 2, 3};
IntStream primitiveStream = Arrays.stream(primitives); // list-backed iterable
PrimitiveIterator.OfInt fromPrimitive1 = primitiveStream.iterator();
Se non puoi utilizzare gli stream (senza java 8), puoi scegliere di utilizzare la libreria guava di google:
Iterable<Integer> fromPrimitive2 = Ints.asList(primitives);
In matrici bidimensionali o più, entrambe le tecniche possono essere utilizzate in un modo leggermente più complesso.
Esempio:
int[][] array = new int[10][10];
for (int indexOuter = 0; indexOuter < array.length; indexOuter++) {
for (int indexInner = 0; indexInner < array[indexOuter].length; indexInner++) {
array[indexOuter][indexInner] = indexOuter + indexInner;
}
}
for (int[] numbers : array) {
for (int value : numbers) {
System.out.println(value);
}
}
È impossibile impostare una matrice su qualsiasi valore non uniforme senza utilizzare un ciclo basato su indice.
Ovviamente puoi anche usare loop while
o do-while
quando si itera usando gli indici.
Una nota di cautela: quando si usano gli indici di matrice, assicurarsi che l'indice sia compreso tra 0
e array.length - 1
(entrambi inclusi). Non fare supposizioni hard coded sulla lunghezza dell'array altrimenti potresti rompere il tuo codice se la lunghezza dell'array cambia ma i tuoi valori hard coded no.
Esempio:
int[] numbers = {1, 2, 3, 4};
public void incrementNumbers() {
// DO THIS :
for (int i = 0; i < numbers.length; i++) {
numbers[i] += 1; //or this: numbers[i] = numbers[i] + 1; or numbers[i]++;
}
// DON'T DO THIS :
for (int i = 0; i < 4; i++) {
numbers[i] += 1;
}
}
È anche la soluzione migliore se non si utilizzano calcoli elaborati per ottenere l'indice ma si utilizza l'indice per ripetere e se è necessario calcolare valori diversi.
Esempio:
public void fillArrayWithDoubleIndex(int[] array) {
// DO THIS :
for (int i = 0; i < array.length; i++) {
array[i] = i * 2;
}
// DON'T DO THIS :
int doubleLength = array.length * 2;
for (int i = 0; i < doubleLength; i += 2) {
array[i / 2] = i;
}
}
Accedere agli array in ordine inverso
int[] array = {0, 1, 1, 2, 3, 5, 8, 13};
for (int i = array.length - 1; i >= 0; i--) {
System.out.println(array[i]);
}
Utilizzare matrici temporanee per ridurre la ripetizione del codice
L'iterazione su una matrice temporanea anziché la ripetizione del codice può rendere il tuo codice più pulito. Può essere utilizzato dove viene eseguita la stessa operazione su più variabili.
// we want to print out all of these
String name = "Margaret";
int eyeCount = 16;
double height = 50.2;
int legs = 9;
int arms = 5;
// copy-paste approach:
System.out.println(name);
System.out.println(eyeCount);
System.out.println(height);
System.out.println(legs);
System.out.println(arms);
// temporary array approach:
for(Object attribute : new Object[]{name, eyeCount, height, legs, arms})
System.out.println(attribute);
// using only numbers
for(double number : new double[]{eyeCount, legs, arms, height})
System.out.println(Math.sqrt(number));
Tenere presente che questo codice non deve essere utilizzato nelle sezioni critiche per le prestazioni, poiché ogni volta che viene immesso il loop viene creato un array e tali variabili primitive vengono copiate nell'array e non possono quindi essere modificate.
Copia di array
Java offre diversi modi per copiare un array.
per ciclo
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Si noti che l'uso di questa opzione con una matrice Oggetto invece di una matrice primitiva riempirà la copia con riferimento al contenuto originale anziché alla sua copia.
Object.clone ()
Poiché gli array sono Object
s in Java, puoi utilizzare Object.clone()
.
int[] a = { 4, 1, 3, 2 };
int[] b = a.clone(); // [4, 1, 3, 2]
Si noti che il metodo Object.clone
per un array esegue una copia superficiale , ovvero restituisce un riferimento a un nuovo array che fa riferimento agli stessi elementi dell'array sorgente.
Arrays.copyOf ()
java.util.Arrays
fornisce un modo semplice per eseguire la copia di un array su un altro. Ecco l'utilizzo di base:
int[] a = {4, 1, 3, 2};
int[] b = Arrays.copyOf(a, a.length); // [4, 1, 3, 2]
Nota che Arrays.copyOf
fornisce anche un overload che ti permette di cambiare il tipo di array:
Double[] doubles = { 1.0, 2.0, 3.0 };
Number[] numbers = Arrays.copyOf(doubles, doubles.length, Number[].class);
System.arraycopy ()
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
Copia una matrice dall'array di origine specificato, iniziando dalla posizione specificata, nella posizione specificata della matrice di destinazione.
Di seguito un esempio di utilizzo
int[] a = { 4, 1, 3, 2 };
int[] b = new int[a.length];
System.arraycopy(a, 0, b, 0, a.length); // [4, 1, 3, 2]
Arrays.copyOfRange ()
Utilizzato principalmente per copiare una parte di una matrice, è anche possibile utilizzarlo per copiare l'intera matrice su un'altra come di seguito:
int[] a = { 4, 1, 3, 2 };
int[] b = Arrays.copyOfRange(a, 0, a.length); // [4, 1, 3, 2]
Casting Arrays
Le matrici sono oggetti, ma il loro tipo è definito dal tipo degli oggetti contenuti. Pertanto, non si può semplicemente trasmettere A[]
a T[]
, ma ogni membro A dello specifico A[]
deve essere lanciato su un oggetto T
Esempio generico:
public static <T, A> T[] castArray(T[] target, A[] array) {
for (int i = 0; i < array.length; i++) {
target[i] = (T) array[i];
}
return target;
}
Pertanto, dato un array A[]
:
T[] target = new T[array.Length];
target = castArray(target, array);
Java SE fornisce il metodo Arrays.copyOf(original, newLength, newType)
per questo scopo:
Double[] doubles = { 1.0, 2.0, 3.0 };
Number[] numbers = Arrays.copyOf(doubles, doubles.length, Number[].class);
Rimuovi un elemento da una matrice
Java non fornisce un metodo diretto in java.util.Arrays
per rimuovere un elemento da una matrice. Per eseguirlo, è possibile copiare l'array originale in uno nuovo senza l'elemento per rimuovere o convertire l'array in un'altra struttura consentendo la rimozione.
Utilizzando ArrayList
È possibile convertire l'array in un java.util.List
, rimuovere l'elemento e riconvertire l'elenco in un array come segue:
String[] array = new String[]{"foo", "bar", "baz"};
List<String> list = new ArrayList<>(Arrays.asList(array));
list.remove("foo");
// Creates a new array with the same size as the list and copies the list
// elements to it.
array = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(array)); //[bar, baz]
Utilizzando System.arraycopy
System.arraycopy()
può essere utilizzato per creare una copia dell'array originale e rimuovere l'elemento desiderato. Di seguito un esempio:
int[] array = new int[] { 1, 2, 3, 4 }; // Original array.
int[] result = new int[array.length - 1]; // Array which will contain the result.
int index = 1; // Remove the value "2".
// Copy the elements at the left of the index.
System.arraycopy(array, 0, result, 0, index);
// Copy the elements at the right of the index.
System.arraycopy(array, index + 1, result, index, array.length - index - 1);
System.out.println(Arrays.toString(result)); //[1, 3, 4]
Utilizzando Apache Commons Lang
Per rimuovere facilmente un elemento, è possibile utilizzare la libreria di Apache Commons Lang e in particolare il metodo statico removeElement()
della classe ArrayUtils
. Di seguito un esempio:
int[] array = new int[]{1,2,3,4};
array = ArrayUtils.removeElement(array, 2); //remove first occurrence of 2
System.out.println(Arrays.toString(array)); //[1, 3, 4]
Array Covariance
Gli array di oggetti sono covarianti, il che significa che proprio come Integer
è una sottoclasse di Number
, Integer[]
è una sottoclasse di Number[]
. Questo può sembrare intuitivo, ma può comportare comportamenti sorprendenti:
Integer[] integerArray = {1, 2, 3};
Number[] numberArray = integerArray; // valid
Number firstElement = numberArray[0]; // valid
numberArray[0] = 4L; // throws ArrayStoreException at runtime
Sebbene Integer[]
sia una sottoclasse di Number[]
, può contenere solo Integer
, e il tentativo di assegnare un elemento Long
genera un'eccezione di runtime.
Si noti che questo comportamento è unico per gli array e può essere evitato utilizzando invece un List
generico:
List<Integer> integerList = Arrays.asList(1, 2, 3);
//List<Number> numberList = integerList; // compile error
List<? extends Number> numberList = integerList;
Number firstElement = numberList.get(0);
//numberList.set(0, 4L); // compile error
Non è necessario che tutti gli elementi dell'array condividano lo stesso tipo, purché siano una sottoclasse del tipo dell'array:
interface I {}
class A implements I {}
class B implements I {}
class C implements I {}
I[] array10 = new I[] { new A(), new B(), new C() }; // Create an array with new
// operator and array initializer.
I[] array11 = { new A(), new B(), new C() }; // Shortcut syntax with array
// initializer.
I[] array12 = new I[3]; // { null, null, null }
I[] array13 = new A[] { new A(), new A() }; // Works because A implements I.
Object[] array14 = new Object[] { "Hello, World!", 3.14159, 42 }; // Create an array with
// new operator and array initializer.
Object[] array15 = { new A(), 64, "My String" }; // Shortcut syntax
// with array initializer.
Come si modifica la dimensione di un array?
La semplice risposta è che non puoi farlo. Una volta creata una matrice, la sua dimensione non può essere modificata. Invece, un array può essere "ridimensionato" solo creando una nuova matrice con le dimensioni appropriate e copiando gli elementi dall'array esistente a quello nuovo.
String[] listOfCities = new String[3]; // array created with size 3.
listOfCities[0] = "New York";
listOfCities[1] = "London";
listOfCities[2] = "Berlin";
Supponiamo (per esempio) che un nuovo elemento debba essere aggiunto alla matrice listOfCities
definita come sopra. Per fare ciò, dovrai:
- creare un nuovo array con dimensione 4,
- copia i 3 elementi esistenti del vecchio array sul nuovo array con gli offset 0, 1 e 2 e
- aggiungi il nuovo elemento al nuovo array all'offset 3.
Ci sono vari modi per fare quanto sopra. Prima di Java 6, il modo più conciso era:
String[] newArray = new String[listOfCities.length + 1];
System.arraycopy(listOfCities, 0, newArray, 0, listOfCities.length);
newArray[listOfCities.length] = "Sydney";
Da Java 6 in poi, i metodi Arrays.copyOf
e Arrays.copyOfRange
possono farlo più semplicemente:
String[] newArray = Arrays.copyOf(listOfCities, listOfCities.length + 1);
newArray[listOfCities.length] = "Sydney";
Per altri modi di copiare un array, fare riferimento al seguente esempio. Tieni presente che per il ridimensionamento hai bisogno di una copia dell'array con una lunghezza diversa rispetto all'originale.
Una migliore alternativa al ridimensionamento degli array
Esistono due principali svantaggi con il ridimensionamento di un array come descritto sopra:
- È inefficiente Rendere un array più grande (o più piccolo) implica copiare molti o tutti gli elementi dell'array esistenti e allocare un nuovo oggetto array. Più grande è l'array, più costoso diventa.
- Devi essere in grado di aggiornare qualsiasi variabile "live" che contiene riferimenti al vecchio array.
Un'alternativa è creare l'array con una dimensione abbastanza grande per iniziare. Questo è possibile solo se è possibile determinare esattamente la dimensione prima di allocare la matrice . Se non è possibile farlo, il problema del ridimensionamento della matrice si ripresenta.
L'altra alternativa è usare una classe di struttura dati fornita dalla libreria di classi Java SE o da una libreria di terze parti. Ad esempio, il framework "collections" di Java SE fornisce una serie di implementazioni delle API List
, Set
e Map
con diverse proprietà di runtime. La classe ArrayList
è la più vicina alle caratteristiche prestazionali di un array semplice (ad es. O (N) lookup, O (1) get e set, O (N) inserimento casuale e cancellazione) fornendo un ridimensionamento più efficiente senza il problema dell'aggiornamento di riferimento.
(L'efficienza di ridimensionamento per ArrayList
deriva dalla sua strategia di raddoppiamento della dimensione dell'array di supporto su ogni ridimensionamento.Per un tipico caso d'uso, questo significa che si ridimensiona solo occasionalmente. Quando si ammortizza per tutta la durata della lista, il costo di ridimensionamento per insert è O(1)
. Potrebbe essere possibile utilizzare la stessa strategia per ridimensionare un array semplice.)
Trovare un elemento in una matrice
Esistono molti modi per trovare la posizione di un valore in una matrice. I seguenti frammenti di esempio presuppongono che l'array sia uno dei seguenti:
String[] strings = new String[] { "A", "B", "C" };
int[] ints = new int[] { 1, 2, 3, 4 };
Inoltre, ognuno imposta index
o index2
sull'indice dell'elemento richiesto o -1
se l'elemento non è presente.
Utilizzo di Arrays.binarySearch
(solo per gli array ordinati)
int index = Arrays.binarySearch(strings, "A");
int index2 = Arrays.binarySearch(ints, 1);
Uso di Arrays.asList
(solo per gli array non primitivi)
int index = Arrays.asList(strings).indexOf("A");
int index2 = Arrays.asList(ints).indexOf(1); // compilation error
Utilizzando un Stream
int index = IntStream.range(0, strings.length)
.filter(i -> "A".equals(strings[i]))
.findFirst()
.orElse(-1); // If not present, gives us -1.
// Similar for an array of primitives
Ricerca lineare usando un ciclo
int index = -1;
for (int i = 0; i < array.length; i++) {
if ("A".equals(array[i])) {
index = i;
break;
}
}
// Similar for an array of primitives
Ricerca lineare utilizzando librerie di terze parti come org.apache.commons
int index = org.apache.commons.lang3.ArrayUtils.contains(strings, "A");
int index2 = org.apache.commons.lang3.ArrayUtils.contains(ints, 1);
Nota: l'utilizzo di una ricerca lineare diretta è più efficiente rispetto al wrapping in un elenco.
Verificare se una matrice contiene un elemento
Gli esempi sopra possono essere adattati per verificare se la matrice contiene un elemento semplicemente testando per vedere se l'indice calcolato è maggiore o uguale a zero.
In alternativa, ci sono anche alcune varianti più concise:
boolean isPresent = Arrays.asList(strings).contains("A");
boolean isPresent = Stream<String>.of(strings).anyMatch(x -> "A".equals(x));
boolean isPresent = false;
for (String s : strings) {
if ("A".equals(s)) {
isPresent = true;
break;
}
}
boolean isPresent = org.apache.commons.lang3.ArrayUtils.contains(ints, 4);
Ordinamento di matrici
Ordinare gli array può essere fatto facilmente con l'API Array .
import java.util.Arrays;
// creating an array with integers
int[] array = {7, 4, 2, 1, 19};
// this is the sorting part just one function ready to be used
Arrays.sort(array);
// prints [1, 2, 4, 7, 19]
System.out.println(Arrays.toString(array));
Ordinamento degli array di stringhe:
String
non è un dato numerico, definisce il proprio ordine che è chiamato ordine lessicografico, noto anche come ordine alfabetico. Quando si ordina una matrice di String usando il metodo sort()
, ordina l'array in un ordine naturale definito dall'interfaccia Comparabile, come mostrato di seguito:
Ordine crescente
String[] names = {"John", "Steve", "Shane", "Adam", "Ben"};
System.out.println("String array before sorting : " + Arrays.toString(names));
Arrays.sort(names);
System.out.println("String array after sorting in ascending order : " + Arrays.toString(names));
Produzione:
String array before sorting : [John, Steve, Shane, Adam, Ben]
String array after sorting in ascending order : [Adam, Ben, John, Shane, Steve]
Decrescente ordine
Arrays.sort(names, 0, names.length, Collections.reverseOrder());
System.out.println("String array after sorting in descending order : " + Arrays.toString(names));
Produzione:
String array after sorting in descending order : [Steve, Shane, John, Ben, Adam]
Ordinamento di una matrice di oggetti
Per ordinare un array di oggetti, tutti gli elementi devono implementare l'interfaccia Comparable
o Comparator
per definire l'ordine dell'ordinamento.
Possiamo usare il metodo sort(Object[])
per ordinare un array di oggetti nel suo ordine naturale, ma è necessario assicurarsi che tutti gli elementi dell'array implementino Comparable
.
Inoltre, devono essere reciprocamente comparabili, ad esempio e1.compareTo(e2)
non deve lanciare ClassCastException
per qualsiasi elemento e1 ed e2 nella matrice. In alternativa è possibile ordinare una matrice di oggetti su ordine personalizzato usando il metodo sort(T[], Comparator)
come mostrato nell'esempio seguente.
// How to Sort Object Array in Java using Comparator and Comparable
Course[] courses = new Course[4];
courses[0] = new Course(101, "Java", 200);
courses[1] = new Course(201, "Ruby", 300);
courses[2] = new Course(301, "Python", 400);
courses[3] = new Course(401, "Scala", 500);
System.out.println("Object array before sorting : " + Arrays.toString(courses));
Arrays.sort(courses);
System.out.println("Object array after sorting in natural order : " + Arrays.toString(courses));
Arrays.sort(courses, new Course.PriceComparator());
System.out.println("Object array after sorting by price : " + Arrays.toString(courses));
Arrays.sort(courses, new Course.NameComparator());
System.out.println("Object array after sorting by name : " + Arrays.toString(courses));
Produzione:
Object array before sorting : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401 Scala@500 ]
Object array after sorting in natural order : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401 Scala@500 ]
Object array after sorting by price : [#101 Java@200 , #201 Ruby@300 , #301 Python@400 , #401 Scala@500 ]
Object array after sorting by name : [#101 Java@200 , #301 Python@400 , #201 Ruby@300 , #401 Scala@500 ]
Conversione di matrici tra primitive e tipi scatolati
A volte è necessaria la conversione di tipi primitivi in tipi in scatola .
Per convertire l'array, è possibile utilizzare gli stream (in Java 8 e versioni successive):
int[] primitiveArray = {1, 2, 3, 4};
Integer[] boxedArray =
Arrays.stream(primitiveArray).boxed().toArray(Integer[]::new);
Con versioni inferiori può essere iterando l'array primitivo e copiandolo esplicitamente all'array scatolato:
int[] primitiveArray = {1, 2, 3, 4};
Integer[] boxedArray = new Integer[primitiveArray.length];
for (int i = 0; i < primitiveArray.length; ++i) {
boxedArray[i] = primitiveArray[i]; // Each element is autoboxed here
}
Allo stesso modo, una matrice in scatola può essere convertita in una matrice della sua controparte primitiva:
Integer[] boxedArray = {1, 2, 3, 4};
int[] primitiveArray =
Arrays.stream(boxedArray).mapToInt(Integer::intValue).toArray();
Integer[] boxedArray = {1, 2, 3, 4};
int[] primitiveArray = new int[boxedArray.length];
for (int i = 0; i < boxedArray.length; ++i) {
primitiveArray[i] = boxedArray[i]; // Each element is outboxed here
}