vettore

strutture ad accesso diretto in grado di contenere più di un valore

Il problema

Una variabile, si sa, può contenere un valore alla volta. Supponiamo allora che vogliamo mantenere, contemporaneamente, tutti i tempi che abbiamo realizzato in un pomeriggio di allenamento in piscina. Per le conoscenze informatiche che abbiamo, il compito sembra piuttosto facile: dichiaro un certo numero di variabili int ciascuna delle quali rappresenta un tempo.

Potremmo per esempio scrivere:
int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
e se di questi tempi vogliamo sapere quanti sono superiori ad un tempo minimo indicato dal coach, come si fa? L'unica soluzione è controllare variabile per variabile il fatto. L'operazione non può essere inserita in un for perché non sono righe identiche: cambia (solo e soltanto) il nome della variabile, in particolare cambierebbe solo il numero che abbiamo apposto in fondo al nome della variabile. Inoltre se un giorno facciamo 15 vasche anziché 10 dobbiamo modificare il programma. Si può inventare qualcosa per cui le azioni si possono mettere nel ciclo?

Un vettore (o array) è una struttura dati che contiene un determinato numero di valori dello stesso tipo.
Per dichiarare un vettore si usa la sintassi
tipo [] nomeVariabile
per assegnare un nuovo vettore ad una variabile si usa la sintassi
nomeVariabile = new tipo[dimensione]
I singoli elementi del vettore sono numerati a partire da zero e si riferiscono usando la sintassi
nomeVariabile[indice]
le variabili di tipo vettore hanno una particolare proprietà chiamata length che definisce il numero di elementi del vettore e si usa scrivendo
nomeVettore.length
Se un vettore viene creato con 10 elementi il primo è il numero 0 e l'ultimo è il numero 9, se si usano indici inferiori allo 0 o superiori al 9 si ottiene un errore "ArrayIndexOutOfBoundsException".

Da notare che i vettori sono variabili di tipo riferimento e prima di essere usati vanno creati usando new (a differenza ad esempio delle varibili int)

Devo dichiarare il vettore spese che conterrà numeri decimali

double spese;questa è una normale variabile non un vettore int [] spese;questo è un vettore ma del tipo sbagliato double [] spese;giusto!

Ho già dichiarato il vettore lunghezze di tipo int [] adesso devo crearlo in modo che possa contenere 5 elementi

lunghezze = new int[]quando si crea un vettore è obbligatorio specificare la dimensione lunghezze = new int[5]giusto! lunghezze = new [5]manca il nome del tipo del vettore

Ho già dichiarato il vettore lunghezze=new int[12] adesso devo caricare nella variabile int tavolo l'ultimo valore del vettore

tavolo = lunghezzesono di tipi diversi tavolo = lunghezze[12]ArrayIndexOutOfBoundsException tavolo = lunghezze[11]giusto! tavolo = lunghezze[0]questo è il primo valore

Ho un vettore chiamato numeri e voglio stampare sulla console la sua lunghezza

numeri.lengthquesto non stampa sulla console System.out.println( numeri )questo non stampa la lunghezza System.out.println( numeri.length )giusto!

Caricamento di un vettore

Dato che un vettore contiene più di un valore vediamo nelle sezioni successive alcune strategie per inserire i valori nel vettore.

Caricamento con elementi casuali

A volte può tornare utile inserire in un vettore tutti numeri casuali (o in effetti un qualsiasi valore)


double v[] = new double[10];
for(int i=0; i<v.length; i++){
    v[i] = Math.random();
}
Se voglio estrarre un numero casuale intero tra 1 e 10 (compresi) posso usare la formula numero = (int)(Math.random()*10+1).

Questo esempio riempie il vettore v con dei numeri decimali maggiori o uguali a zero e minori di 1.

Caricamento di un elemento alla volta

Il frammento di programma sotto riporta lo schema normalmente utilizzato quando è necessario leggere un numero alla volta. In pratica l'utente scrive un numero e fa click su un pulsante, poi ne inserisce un altro e via di seguito.

In questo caso la lunghezza del vettore è stabilita a priori.


public class Numeri extends Application {
   TextField tNumero = new TextField();
   int numeri[];
   int numeriInseriti;

   @Override
   public void start(Stage primaryStage) {
      /* Quanto necessario per la grafica... */

      // creo un vettore con 10 posti
      numeri = new int[10];
      // tengo traccia di quanti ne ho già messi
      // (nessuno all'inizio)
      numeriInseriti = 0;

      pInserisci.setOnAction( e-> inserisciNumero() );
   }

   public void inserisciNumero() {
      // controllo se ho ancora spazio per inserire un nuovo numero
      if(numeriInseriti < numeri.length) {
         // leggo il numero dalla casella, lo trasformo in intero
         // e lo inserisco nella posizione opportuna del vettore
         numeri[numeriInseriti]=Integer.parseInt(tNumero.getText());
         // mi preparo per il prossimo inserimento
         numeriInseriti++;
         tNumero.setText(""); // pulisco la casella di testo rendendola pronta per il prossimo inserimento
      }
   }

}

Caricamento da un elenco

Il frammento di programma sotto riporta lo schema normalmente utilizzato quando è necessario leggere una sequenza di numeri separati da una virgola (o altro) presenti in una stringa e inserirli in un vettore.


// la stringa potrebbe anche essere letta da una casella
String testo = "1,8,12,19,21";
// separo i singoli elementi della stringa in un vettore di oggetti di tipo String
// è direttamente split che crea il vettore
String parti[] = testo.split(",");
// dichiaro e creo un vettore di numeri della stessa lunghezza
int [] numeri = new int[parti.length];
// inserisco i singoli elementi nel vettore numeri trasformandoli dal 
// testo presente in parti nella posizione corrispondente
for(int i=0 ; i<parti.length; i++ ){
    numeri[i] = Integer.parseInt( parti[i] );
}

Quale dei seguenti blocchi di codice è equivalente a tempi[pos++]=Integer.parseInt(tTempo.getText());

pos=pos+1;
tempi[pos]=Integer.parseInt(tTempo.getText());
tempi[pos]=Integer.parseInt(tTempo.getText());
pos=pos+1;
int o;
o=Integer.parseInt(tTempo.getText());
tempi[pos++]=o