PDA

View Full Version : [JAVA] Gestione degli array


skyblu_angel
19-02-2010, 14:34
Sto studiando gli array in java e sto provando a scrivere parecchio codice sulle possibili operazioni da fare su di essi.

Al momento sono in difficoltà su un paio di operazioni:
1 - svuotare l'array
2 - modificare la capacità dell'array(non mi interessa mantenere il suo contenuto)

Mi spiego meglio:
1- ho bisogno di svuotare l'array da tutto il suo contenuto. So che mi basta fare un ciclo dove setto tutti i campi dell'array su null o comunque un valore standard.

2 - ho bisogno di cambiare la capacità dell'array ma se faccio così:
array = new String[nuova_dimensione]

Non accade nulla. Nè svuota l'array, nè cambia il contenuto, nè modifica le sue dimensioni.

In conclusione: il problema più grosso è il passo numero 2.

Accetto consigli...

PGI-Bis
19-02-2010, 15:01
In verità non puoi cambiare la capacità di un array.

Puoi fare quello che giustamente fai nel punto due, cioè creare un nuovo array e assegnarlo ad una variabile già esistente.

Deve funzionare per forza. Cioè se dici:

String[] array = new String[10];
System.out.println("array size: " + array.length);
array = new String[20];
System.out.println("array size: " + array.length);

saltano fuori 10 e 20 senza possibilità di scampo.

vladix
19-02-2010, 15:01
non serve fare un ciclo per svuotare l'array ma basta reistanziarlo ... per il punto 2 quello che scrivi e una cosa assurda , ti mostro qui un pezzo di codice funzionante ... ( che fa la stessa cosa che hai descritto )



String [] xd = new String [3];

xd[0] = "a";
xd[1] = "b";
xd[2] = "c";

for(String d : xd){

System.out.println(d);
}

// svuoto l'array e reimposto la capacità ...
xd = new String [4];

for(String d : xd){

System.out.println(d);
}

skyblu_angel
19-02-2010, 15:10
In verità non puoi cambiare la capacità di un array.

Puoi fare quello che giustamente fai nel punto due, cioè creare un nuovo array e assegnarlo ad una variabile già esistente.

Deve funzionare per forza. Cioè se dici:

String[] array = new String[10];
System.out.println("array size: " + array.length);
array = new String[20];
System.out.println("array size: " + array.length);

saltano fuori 10 e 20 senza possibilità di scampo.

Ti posto il mio codice:

// rigenera array con nuova capacità massima
System.out.print("Inserisci la nuova capacità massima dell'array : ");
appoggio=tastiera.readLine();
dimensione_max=Integer.parseInt(appoggio);
TipoArray.rigenera(giochino, dimensione_max );

public void rigenera(String[] arrayx, int nuovaDimensione){

for (int c=0;c<arrayx.length;c++){ //svuotamento array
arrayx[c]=null;
}
arrayx = new String[nuovaDimensione];
System.out.println("Operazione avvenuta con successo.\nLa nuova massima capacità è di : "+arrayx.length+"\n");
}

Come puoi vedere, nel metodo rigenera effettuo l'operazione che mi dicevi prima te:
arrayx = new String[nuovaDimensione];
Ma non accade nulla!
Come se non facessi niente... L'array rimane invariato :confused:

banryu79
19-02-2010, 15:13
Punto 1: ti sei gia' risposto da solo.
Tenendo presente che in Java puoi avere array di tipi primitivi o array di riferimenti, in entrambi i casi e' comunque sufficiente valorizzare i singoli elementi assegnando loro il valore di default previsto per quel tipo, proprio come hai detto.

Punto 2: dunque, cambiare la capacità dell'array significa o aumentare o diminuire il numero di elementi che esso può contenere.
Bisogna tenere presente che gli array non sono "dinamici": una volta creato, un array non cambia dimensione. Bisogna creare un nuovo oggetto array specificando per esso la nuova dimensione desiderata, quindi copiare gli elementi dell'array originale in quello nuovo.
Considerando il fatto di voler copiare gli elementi del vecchio array sul nuovo, in caso di un aumento di dimensioni, non ci sono particolari problemi.
In caso di diminuzione invece si presenta il caso in cui il nuovo array sia di dimensione insufficiente a contenere tutti gli elementi presenti in quello originario.

Detto questo, se nel codice che hai postato 'array' è dichiarato di tipo String[], francamente non vedo problemi: l'array verrà reinizializzato con la dimensione che hai specificato e che tutti gli elementi a null.

skyblu_angel
19-02-2010, 15:19
Ecco come ho risolto:

Se utilizzo : arrayx = new String[nuova_dimensione];
All'interno di un metodo che vado a richiamare nel main, non accade nulla.
Se invece la scrivo all'interno del main funziona.

Qualcuno può spiegarmi il motivo?

PGI-Bis
19-02-2010, 15:28
l'argomento del metodo è una variabile diversa da quella che usi quando invochi lo stesso metodo. Capita allora che se riassegni "l'argomento" è quest'ultimo che va a puntare ad un diverso valore mentre la variabile usata per l'invocazione (il cd parametro) resta dov'era.

skyblu_angel
19-02-2010, 15:33
l'argomento del metodo è una variabile diversa da quella che usi quando invochi lo stesso metodo. Capita allora che se riassegni "l'argomento" è quest'ultimo che va a puntare ad un diverso valore mentre la variabile usata per l'invocazione (il cd parametro) resta dov'era.

Dato che ho postato il codice, mi diresti quindi dove è l'errore? :confused:

banryu79
19-02-2010, 15:58
Dato che ho postato il codice, mi diresti quindi dove è l'errore? :confused:
Te l'ha detto proprio nelle frasi che hai quotato.
L'errore è che nello scope del tuo 'metodo' rigenera l'oggetto 'arrayx' è una copia dell'array di String che hai creato nello scope del metodo 'main'.

Quindi quando nel metodo 'rigenera' esegui delle operazioni su 'arrayx', stai solo modificando una variabile locale; quando poi il metodo 'rigenera' termina, la variabile 'arrayx' locale viene distrutta.
E l'array "esterno", quello dichiarato nello scope del metodo 'main', non viene neanche sfiorato.

Risolvi tutto semplicemente gettando ai pesci il meotodo 'rigenera' ed effettuando un normale assegnamento:

// nel metodo main
giochino = new String[nuovaDimensione];

PGI-Bis
19-02-2010, 16:05
Non è un errore nel senso che il tuo codice è corretto. E non è un problema di array ma di puntatori.

Questo è il tuo metodo rigenera:

public void rigenera(String[] array, int nuovaDimensione) {
array = new String[nuovaDimensione];
}

quando lo invochi:

giochino = un certo array di stringhe
dimensione_max = leggi...
rigenera(giochino, dimensione_max);

rigenera si trova per le mani un puntatore allo stesso valore di giochino - solo che in rigenera quando scrivi:

array = new String[nuovaDimensione]

le strade di questi due puntatori si dividono.

Quando scrivi tutto nel main, non c'è nulla da dividere: non ci sono due puntatori, ce n'è uno solo:

giochino = un certo array di stringhe
dimensione_max = leggi...
giochino = new String[dimensione_max];

E' la stessa cosa che capita se diciamo:

public void metodo(int argomento) {
argomento = 50;
}

int valore = 10;
metodo(valore);
System.out.println(valore);

Stampa 10, non 50. Come fai a fargli stampare 50? La via idiomatica - cioè quel che tipicamente scriviamo in Java - passa per la restituzione di un valore da parte del metodo.

public int metodo(int argomento) {
argomento = 50;
return argomento;
}

int valore = 10;
valore = metodo(valore);
System.out.println(valore);

Lo stesso vale nel caso dell'array:

public String[] rigenera(String[] array, int nuovaDimensione) {
return new String[nuovaDimensione];
}

int max = leggi un intero...
giochini = rigenera(giochini, max);

Dal che si capisce che rigenera non ha poi un gran bisogno dell'argomento di tipo String[]

public String rigenera(int nuovaDimensione) {
return new String[nuovaDimensione];
}

int max = leggi un intero
giochini = rigenera(max);

L'argomento di tipo String[] servirebbe se prima di riassegnare giochini dovessimo fare qualche genere di operazione sui valori originali o se il nuovo array dovesse avere dei valori che dipendono dai vecchi. Tieni conto che non è necessario impostare a null i valori di un array se questo è destinato ad essere scartato dal garbage collector.

skyblu_angel
19-02-2010, 16:42
Ok...

ho corretto scrivendo tutto nel main ed ho risolto..