RISOLTO Popolare ArrayList<Object>

simo9115

Nuovo Utente
139
3
Salve a tutti.
Ho implementato questa classe "Edge":
Codice:
public class Edge {
    
    
    String EdgeName;
    String EdgeToken;
    
        
    public void insertEdgeName(String name)
    {
        
        this.EdgeName = name; 
    }
    
    public void insertEdgeToken(String token)
    {
        
        this.EdgeToken = token;
        
    }
    
    public void printEdge(Edge e)
    {
        System.out.println("EdgeName: "+EdgeName);
        System.out.println("EdgeToken: "+EdgeToken);        
    }
    
    public void printEdgeList(ArrayList <Edge> Edge)
    {
        for(int i=0; i<Edge.size(); i++)
        {
            printEdge(Edge.get(i));
        }
    }
    
}

Questa classe mi serve per popolare un ArrayList di Oggetti di tipo Edge e per farlo ho scritto su un'altra classe "Gateway" questo metodo:
Codice:
public ArrayList<Edge> Edge(ArrayList<String> ArrayEdge)
    {
        Edge edge1 = new Edge(); //oggetto Edge di appoggio
        ArrayList<Edge> listEdge = new ArrayList<Edge>();
        for(int i=0; i<ArrayEdge.size();)
            {
                String name = ArrayEdge.get(i);
                System.out.println("Name"+i+": "+name);
                edge1.insertEdgeName(name);
                i++;
                String token = ArrayEdge.get(i);
                System.out.println("Token"+i+": "+token);
                edge1.insertEdgeToken(token);
                i++;
                listEdge.add(edge1);
                
            }
        
        edge1.printEdgeList(listEdge);
        return listEdge;
    }
Come potete vedere prendo degli elementi da ArrayList<String> ArrayEdge, vado a crearmi un oggetto di tipo Edge e l'aggiungo ArrayList<Edge> Edge.
ArrayEdge è formato da :
Codice:
0: "signavio:SequenceFlow_1" 
1:  0 
2:  "signavio:sid-E3D5ED09-D303-4195-8E27-516CF4D132AF" 
3:  0
solo che quando vado a stampare l'arrayList Edge con il metodo printEdgeList mi stampa:
Codice:
EdgeName:  "signavio:sid-E3D5ED09-D303-4195-8E27-516CF4D132AF" 
EdgeToken:  0
EdgeName:  "signavio:sid-E3D5ED09-D303-4195-8E27-516CF4D132AF" 
EdgeToken:  0
perchè mi salva anche nell'indice 0 il contenuto dell'indice 1? non dovrebbe aggiungere 2 elementi distinti?
grazie a tutti per l'aiuto
 

1nd33d

Utente Attivo
653
279
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
HDD
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
GPU
XFX RX480 GTR Black Edition
Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
PSU
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
OS
Windows 10 64bit - Linux Mint 18
re: Popolare ArrayList<Object>

Innanzi tutto un paio di note implementative (rientrano nell'argomento "ingegneria del software", non pregiudicano il funzionamento del programma, ma sarebbero da tenere in considerazione):
- scrivi un costruttore per la classe Edge in modo che assegni subito nome e token, non ha senso chiamare 3 metodi (costruttore implicito e due set) quando ne puoi chiamare uno.
- il metodo printEdgeList non ha senso nella classe Edge... un oggetto non stampa una lista di altri oggetti, semmai stampa solo se stesso. Eventualmente puoi estendere ArrayList e aggiungere quel metodo, oppure puoi direttamente fare un override del print di ArrayList.
- attento coi nomi, quella lista di stringhe e l'altra di oggetti si confondono, e in generale mi è poco chiaro come le usi, penso che l'algoritmo sia un po' da rivedere. Giusto per capire... nella lista di stringhe che passi al metodo, ci sono nomi e token in posizioni alterne?

Per quanto riguarda l'errore del tuo programma, è palese. In Java esistono due tipi di dati: primitivi (int, char, double...) e oggetti.
In java gli oggetti sono riferiti mediante puntatore e il passaggio di parametri avviene per valore. Cosa significa? Semplicemente che nel tuo ciclo for stai lavorando sempre con lo stesso oggetto (edge1) e ogni volta gli riassegni nome e token. Quando vai a inserirlo nell'array, in realtà stai solo copiando il suo indirizzo, quindi alla fine l'array sarà popolato da riferimenti allo stesso oggetto edge1 i cui campi corrisponderanno all'ultimo Name e Token inseriti.
Ad ogni ciclo devi creare un nuovo oggetto Edge.
 
Ultima modifica:

simo9115

Nuovo Utente
139
3
re: Popolare ArrayList<Object>

Innanzi tutto un paio di note implementative (rientrano nell'argomento "ingegneria del software", non pregiudicano il funzionamento del programma, ma sarebbero da tenere in considerazione):
- scrivi un costruttore per la classe Edge in modo che assegni subito nome e token, non ha senso chiamare 3 metodi (costruttore implicito e due set) quando ne puoi chiamare uno.
- il metodo printEdgeList non ha senso nella classe Edge... un oggetto non stampa una lista di altri oggetti, semmai stampa solo se stesso. Eventualmente puoi estendere ArrayList e aggiungere quel metodo, oppure puoi direttamente fare un override del print di ArrayList.
- attento coi nomi, quella lista di stringhe e l'altra di oggetti si confondono, e in generale mi è poco chiaro come le usi, penso che l'algoritmo sia un po' da rivedere. Giusto per capire... nella lista di stringhe che passi al metodo, ci sono nomi e token in posizioni alterne?

Per quanto riguarda l'errore del tuo programma, è palese. In Java esistono due tipi di dati: primitivi (int, char, double...) e oggetti.
In java gli oggetti sono riferiti mediante puntatore e il passaggio di parametri avviene per valore. Cosa significa? Semplicemente che nel tuo ciclo for stai lavorando sempre con lo stesso oggetto (edge1) e ogni volta gli riassegni nome e token. Quando vai a inserirlo nell'array, in realtà stai solo copiando il suo indirizzo, quindi alla fine l'array sarà popolato da riferimenti allo stesso oggetto edge1 i cui campi corrisponderanno all'ultimo Name e Token inseriti.
Ad ogni ciclo devi creare un nuovo oggetto Edge.

innanzitutto ti ringrazio per l'aiuto ;)
ArrayList che passo al metodo è questo :
Codice:
EdgeName:  "signavio:sid-E3D5ED09-D303-4195-8E27-516CF4D132AF" 
EdgeToken:  0
EdgeName:  "signavio:sid-E3D5ED09-D303-4195-8E27-516CF4D132AF" 
EdgeToken:  0
praticamente il nome compreso tra virgolette sarebbe il Name e il numero il Token in posizioni alterne.
Per quando riguarda il metodo io avevo già capito che lavorando sempre con lo stesso oggetto edge1 mi provocasse questo errore...però credevo che nel momento che io l'aggiungevo ad ArrayList <Edge> Edge mi salvava valori diversi non andando a modificare quelli salvati nell'indice precendente. la questione però sta nel fatto che al metodo passo si un arrayList ma purtroppo è di lunghezza variabile(in questo caso ha lunghezza 4 ma potrei avere un arrayList grande N elementi). come faccio io a creare oggetti di tipo Edge se non so quanti me ne servono?cioè mi servirebbero N oggetti di tipo Edge a seconda di quanti elementi è composta l'arrayList che passo al metodo...spero di essermi spiegato bene ;)
 

1nd33d

Utente Attivo
653
279
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
HDD
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
GPU
XFX RX480 GTR Black Edition
Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
PSU
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
OS
Windows 10 64bit - Linux Mint 18
re: Popolare ArrayList<Object>

come faccio io a creare oggetti di tipo Edge se non so quanti me ne servono?cioè mi servirebbero N oggetti di tipo Edge a seconda di quanti elementi è composta l'arrayList che passo al metodo...spero di essermi spiegato bene ;)
Beh.. il ciclo ce l'hai, quindi crei un nuovo oggetto ad ogni iterazione no?
Codice:
        Edge edge1; //oggetto Edge di appoggio, ***solo dichiarazione***
        ArrayList<Edge> listEdge = new ArrayList<Edge>();
        for(int i=0; i<ArrayEdge.size();)
            {
                edge1 = new Edge(); //nuova istanza
                String name = ArrayEdge.get(i);
                System.out.println("Name"+i+": "+name);
                edge1.insertEdgeName(name);
                i++;
                String token = ArrayEdge.get(i);
                System.out.println("Token"+i+": "+token);
                edge1.insertEdgeToken(token);
                i++;
                listEdge.add(edge1);
                
            }        
        edge1.printEdgeList(listEdge);
        return listEdge;
Questa è la modifica più immediata.
Se fornisci ad Edge un costruttore completo potresti anche ottimizzare il codice:
Codice:
        ArrayList<Edge> listEdge = new ArrayList<Edge>();
        for(int i=0; i<ArrayEdge.size();)
            {
                String name = ArrayEdge.get(i);
                System.out.println("Name"+i+": "+name);
                i++;
                String token = ArrayEdge.get(i);
                System.out.println("Token"+i+": "+token);
                i++;
                listEdge.add(new Edge(name, token));                
            }        
        Edge.printEdgeList(listEdge);
        return listEdge;
In questo caso non usi variabili di tipo Edge. Alla fine tu chiameresti il printEdgeList su un oggetto di tipo Edge, come ti ho detto non ha molto senso, non è "bello" programmativamente parlando. Per due motivi:
- come detto prima, il metodo di un oggetto si dovrebbe occupare dell'oggetto stesso e non stampare altre cose
- per essere richiamato, devi creare prima un oggetto di tipo Edge, non ha senso... tanto vale a questo punto che il metodo sia statico, visto che non usi l'oggetto su cui lo richiami (vedi punto precedente).

Nel secondo codice che ti ho postato ho ipotizzato che il metodo printEdgeList sia statico, già avrebbe più senso, ma se vuoi fare una cosa fatta bene io estenderei ArrayList con override di toString().

Penso che addirittura quel ciclo si riesca a ridurre a una sola riga (escludendo gli output di debug che comunque dovresti togliere):
Codice:
        ArrayList<Edge> listEdge = new ArrayList<Edge>();
        for(int i=0; i<ArrayEdge.size();)
                listEdge.add(new Edge(ArrayEdge.get(i++), ArrayEdge.get(i++)));  
        
        Edge.printEdgeList(listEdge);
        return listEdge;
ps: in quest'ultima variante è importante che nell'array di stringhe il nome venga prima del token e che il costruttore prenda i parametri nello stesso ordine. Personalmente non amo mescolare dati concettualmente diversi nella stessa struttura, forse avrei fatto due array distinti: uno per i nomi e uno per i token. Oppure avrei direttamente popolato l'arraylist di Edge senza passaggi intermedi.
 
Ultima modifica:

simo9115

Nuovo Utente
139
3
re: Popolare ArrayList<Object>

Beh.. il ciclo ce l'hai, quindi crei un nuovo oggetto ad ogni iterazione no?
Codice:
        Edge edge1; //oggetto Edge di appoggio, ***solo dichiarazione***
        ArrayList<Edge> listEdge = new ArrayList<Edge>();
        for(int i=0; i<ArrayEdge.size();)
            {
                edge1 = new Edge(); //nuova istanza
                String name = ArrayEdge.get(i);
                System.out.println("Name"+i+": "+name);
                edge1.insertEdgeName(name);
                i++;
                String token = ArrayEdge.get(i);
                System.out.println("Token"+i+": "+token);
                edge1.insertEdgeToken(token);
                i++;
                listEdge.add(edge1);
                
            }        
        edge1.printEdgeList(listEdge);
        return listEdge;
Questa è la modifica più immediata.
Se fornisci ad Edge un costruttore completo potresti anche ottimizzare il codice:
Codice:
        ArrayList<Edge> listEdge = new ArrayList<Edge>();
        for(int i=0; i<ArrayEdge.size();)
            {
                String name = ArrayEdge.get(i);
                System.out.println("Name"+i+": "+name);
                i++;
                String token = ArrayEdge.get(i);
                System.out.println("Token"+i+": "+token);
                i++;
                listEdge.add(new Edge(name, token));                
            }        
        Edge.printEdgeList(listEdge);
        return listEdge;
In questo caso non usi variabili di tipo Edge. Alla fine tu chiameresti il printEdgeList su un oggetto di tipo Edge, come ti ho detto non ha molto senso, non è "bello" programmativamente parlando. Per due motivi:
- come detto prima, il metodo di un oggetto si dovrebbe occupare dell'oggetto stesso e non stampare altre cose
- per essere richiamato, devi creare prima un oggetto di tipo Edge, non ha senso... tanto vale a questo punto che il metodo sia statico, visto che non usi l'oggetto su cui lo richiami (vedi punto precedente).

Nel secondo codice che ti ho postato ho ipotizzato che il metodo printEdgeList sia statico, già avrebbe più senso, ma se vuoi fare una cosa fatta bene io estenderei ArrayList con override di toString().

Penso che addirittura quel ciclo si riesca a ridurre a una sola riga (escludendo gli output di debug che comunque dovresti togliere):
Codice:
        ArrayList<Edge> listEdge = new ArrayList<Edge>();
        for(int i=0; i<ArrayEdge.size();)
                listEdge.add(new Edge(ArrayEdge.get(i++), ArrayEdge.get(i++)));  
        
        Edge.printEdgeList(listEdge);
        return listEdge;
ps: in quest'ultima variante è importante che nell'array di stringhe il nome venga prima del token e che il costruttore prenda i parametri nello stesso ordine. Personalmente non amo mescolare dati concettualmente diversi nella stessa struttura, forse avrei fatto due array distinti: uno per i nomi e uno per i token. Oppure avrei direttamente popolato l'arraylist di Edge senza passaggi intermedi.

grazie mille per l'aiuto! sia per l'aiuto ma soprattutto per la chiarezza nel spiegarmi i concetti! grazie veramente grazie
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!