Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    Concatenare un numero arbitrario di matrici n x 4: problemi

    Salve gente,

    sto cercando di creare un metodo Java che dato in ingresso un Vector<Object[][]> mi restituisca una matrice di Object che è la concatenazione di tutte quelle nel Vector.
    Esempio:
    Matrice 1 di 4 colonne:
    1 2 3 4
    5 6 7 8

    Matrice 2 di 4 colonne:

    9 10 11 12
    13 14 15 16
    17 18 19 20

    Vorrei che restituisse:
    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 16
    17 18 19 20

    Come posso fare?

    Il metodo che ho scritto io è il seguente:
    codice:
    public static Object[][] unisciMatrici(Vector<Object[][]> v){
    		int rows = 0;
    		int k = 0;
    		for(int i=0;i<v.capacity();i++){
    			rows+=v.get(i).length;
    		}
    		Object[][] res = new Object[rows][4];
    		for(int i=0;i<v.capacity() && k<res.length;i++){
    			for(int j = 0; j<v.get(i).length;j++){
    				res[k][0] = v.get(i)[j][0];
    				res[k][1] = v.get(i)[j][1];
    				res[k][2] = v.get(i)[j][2];
    				res[k][3] = v.get(i)[j][3];
    				k++;
    			}
    		}
    		
    		return res;
    	}
    Il problema è che non funziona, e già nel primo for mi da problemi. Non riesco a capire perché il metodo che uso per determinare il numero di righe della nuova matrice sia sbagliato.
    Io voglio semplicemente trovare il numero di righe sommando, il numero di righe di ciascuna matrice contenuta in ogni cella del vector.

    Qual'è l'errore?
    Ci sto sbattendo la testa da ore ed ore, e non trovo una soluzione.

    Grazie.

    EDIT: Risolto porca miseria... dovevo usare size() e non capacity() !!!

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    C'è una soluzione, un po' più semplice e tra l'altro più "generale" in cui il unisciMatrici non deve "sapere" di dover trattare 4 colonne precise.

    1) Calcoli il numero totale di righe (questo l'hai già fatto avendo anche visto la questione del size() invece di capacity() ).

    2) Istanzi l'array Object[][] senza specificare il numero di colonne:

    Object[][] res = new Object[rows][];

    Non c'è il numero di colonne, ma questo è perfettamente lecito!

    3) Fai un ciclo su Vector/righe (come hai già fatto) e per ogni reference al sotto-array (ricordiamo sempre che gli array multidimensione sono semplicemente "array di array") puoi decidere di fare una tra 2 cose: a) Copiare pari pari il reference all'array delle colonne (shallow-copy) oppure b) clonare (con clone()) l'array delle colonne.

    Semplice, pulito e non devi accedere alle colonne.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Grazie!

    Qualcosa del genere?
    codice:
    public static Object[][] unisciMatrici(Vector<Object[][]> v){
    		int rows = 0;
    		int k = 0;
    		for(int i=0;i<v.size();i++){
    			rows+=v.get(i).length;
    		}
    		Object[][] res = new Object[rows][];
    		for(int i=0;i<v.capacity() && k<res.length;i++){
    			for(int j = 0; j<v.get(i).length;j++){
    				res[k] = v.get(i)[j];
    				k++;
    			}
    		}
    		
    		return res;
    	}
    Così sembrerebbe funzionare in effetti...

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da fbcyborg
    Qualcosa del genere?
    Così sembrerebbe funzionare in effetti...
    Intanto vedo ancora un capacity() e questo non ti serve. Nella seconda parte dovresti fare un ciclo usando v.size() esattamente come il primo ciclo. E il test k<res.length potresti anche toglierlo.
    La variabile 'k' ovviamente ti serve comunque per avanzare nelle righe del nuovo array.

    E lo ribadisco, copiando pari pari i reference all'array delle colonne con:

    res[k] = v.get(i)[j];

    hai fatto uno "shallow copy". Nell'array restituito dal metodo l'array principale delle righe è nuovo (istanziato con il new Object[rows][] ). Ma poi "vede" gli stessi identici array delle colonne che ci sono negli array nel Vector.
    Nulla di sbagliato di per sé in questo ... se ti va bene ed è appropriato per quello che devi fare, ok.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Hai ragione, mi ero dimenticato di usare size() anche nel secondo caso. Anche se funzionava lo stesso, non so perché...
    Allora ho modificato il codice nel modo seguente:
    codice:
    public static Object[][] unisciMatrici(Vector<Object[][]> v){
    		int rows = 0;
    		int k = 0;
    		for(int i=0;i<v.size();i++){
    			rows+=v.get(i).length;
    		}
    		Object[][] res = new Object[rows][];
    		for(int i=0;i<v.size();i++){
    			for(int j = 0; j<v.get(i).length;j++){
    				res[k] = v.get(i)[j];
    				k++;
    			}
    		}
    		
    		return res;
    	}
    Per quanto riguarda la "shallow" copy, sinceramente non ho capito bene quale sia il problema. Ti dispiacerebbe farmi un esempio per favore?

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da fbcyborg
    Anche se funzionava lo stesso, non so perché...
    Funzionava lo stesso perché c'era il k<res.length che limitava il range impedendo di andare "fuori" dal Vector, anche se il capacity fosse stato maggiore.

    Originariamente inviato da fbcyborg
    Per quanto riguarda la "shallow" copy, sinceramente non ho capito bene quale sia il problema. Ti dispiacerebbe farmi un esempio per favore?
    Guarda cosa dicevo in questo post. Lì parlavo del clone() .... ma tu hai fatto più o meno la stessa cosa (concettualmente parlando).
    L'array principale che ritorni è nuovo ma il contenuto (reference ad altri array) "punta" esattamente agli stessi identici array originali {1,2,3,4} {5,6,7,8} (chiaramente i valori saranno degli Integer o Long non so, ma non primitivi) ecc... che ci sono negli array nel Vector ricevuto in input.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Ah, ho capito. E' vero.
    Però allora ora mi viene un vergognoso dubbio...
    L'istruzione
    codice:
    res[k] = v.get(i)[j];
    Perché fa puntare res[k] al valore contenuto in v.get(i)[j], e invece non gli viene proprio assegnato in quella casella?
    Io con quella istruzione volevo dire:
    alla locazione di memoria identificata da res[k] assegna il valore contenuto in v.get(i)[j].
    Perché non è così?

    Occorrerebbe un
    codice:
    res[k] = new Object(v.get(i)[j]);
    ???

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da fbcyborg
    codice:
    res[k] = v.get(i)[j];
    Perché fa puntare res[k] al valore contenuto in v.get(i)[j], e invece non gli viene proprio assegnato in quella casella?
    Io con quella istruzione volevo dire:
    alla locazione di memoria identificata da res[k] assegna il valore contenuto in v.get(i)[j].
    Perché non è così?
    Ma è appunto così!! Il fatto è che questo valore (l'espressione v.get(i)[j] intendo) denota un "reference" che alla fin fine è un valore (solo più particolare poiché ha senso per la JVM ... non per il programmatore).
    Tu stai assegnando a res[k] un valore che è il reference all'array. In generale se 2 variabili reference distinte hanno lo stesso valore (non null, chiaramente) allora "puntano" allo stesso identico oggetto.

    Originariamente inviato da fbcyborg
    Occorrerebbe un
    codice:
    res[k] = new Object(v.get(i)[j]);
    ???
    No, basta un clone():

    res[k] = v.get(i)[j].clone();

    A questo punto la struttura dell'array ritornato dal tuo metodo sarebbe tutta nuova. L'unica cosa che rimane ancora "shallow" è il fatto che all'interno del tuo array si fa riferimento agli stessi identici oggetti Integer (o quello che è per i valori numerici) che ci sono negli array originali.

    Ma se sono Integer (o altro wrapper) sono oggetti "immutabili", quindi anche se sono condivisi non è un problema.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Ahh!
    OK.

    Per quanto riguarda il problema di "shallow" rimanente, purtroppo la matrice non è di int, ma di oggetti di diverso tipo, a seconda della colonna della matrice.
    Ad esempio ho dei "Date", delle String, int, e un altro tipo che ora non mi sovviene .
    Fino ad ora non ho mai avuto problemi. Dovrebbe succedere qualcosa di strano?

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da fbcyborg
    Per quanto riguarda il problema di "shallow" rimanente, purtroppo la matrice non è di int, ma di oggetti di diverso tipo, a seconda della colonna della matrice.
    All'inizio hai fatto degli esempi di matrici con valori numerici ..... quindi avevo presupposto Integer (o altro wrapper es. Long).

    Originariamente inviato da fbcyborg
    Ad esempio ho dei "Date", delle String, int, e un altro tipo che ora non mi sovviene .
    Nel Object[] (l'array delle colonne) non puoi avere primitivi .... al massimo i wrapper Integer ecc...

    Originariamente inviato da fbcyborg
    Fino ad ora non ho mai avuto problemi. Dovrebbe succedere qualcosa di strano?
    Se gli oggetti dei tuoi valori nel Vector<Object[][]> sono "immutabili" non c'è alcun problema.
    Con il clone() che ho suggerito sopra la struttura dell'array che ritorni è tutta completamente nuova, separata dagli Object[][] originali nel Vector.

    Nel nuovo array puoi assegnare ad una cella un reference ad un nuovo/altro oggetto Date, String, ecc... ovviamente. Ed essendo la struttura duplicata non va a toccare nulla negli array originali.

    Se gli oggetti sono "immutabili" non puoi cambiare il loro stato. Quindi anche se vedi lo stesso identico oggetto da due strutture dati differenti, se non puoi alterarlo ripeto che non ci sono problemi.

    Se fossero mutabili, il problema ci potrebbe essere: una modifica ad un oggetto nel Vector<Object[][]> la "vedi" anche attraverso il tuo nuovo Object[][] che ritorni.
    E Date, per inciso, è "mutabile".

    Spero che hai capito la "finezza" di queste problematiche.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.