ArrayList e compareTo

di il
20 risposte

ArrayList e compareTo

Buonasera, avrei un problema riguardante il compareTo su un ArrayList.

Vi spiego il problema:

Devo realizzare un metodo che permette di ordinare un ArrayList di tipo <Operaio> (dove questo ArrayList si trova in un costruttore di una classe chiamata Operazioni "Di seguito c'è il codice"). Devo restituire le 3 Operazioni che hanno coinvolto piu operai. La classe Operazione tiene conto degli operai che hanno partecipato a una Operazione specifica data dalla vaiabile "TIPO" dove questa contiene l'operazione svolta dall'operaio es: aratura di un terreno, una semina,taglio alberi ecc.
import java.util.*;
public class Operazioni implements Comparable <Operazioni>{
	
	private int data;
	private String tipo;
	public ArrayList <Operaio> operaiPartecipano = new ArrayList <Operaio> ();
	
	
	public Operazioni (int data,String tipo, ArrayList <Operaio> operaiPartecipano)
	
	{
		this.data = data;
		this.tipo = tipo;
		this.operaiPartecipano = new ArrayList <Operaio> (operaiPartecipano);
		
		
		
	}
	
	
	public int getData ()
	
	{
		return data;
		
	}
	
	public String getTipo ()
	
	{
		return tipo;
		
	}
	
	
	public ArrayList<Operaio> getOperaiPartecipano ()
	
	{
		return new ArrayList <Operaio> (operaiPartecipano);
		
		
	}
	
	
	@SuppressWarnings("unchecked")
	public int compareTo (Operazioni o)
	
	{
		
		return ((Comparable<Operazioni>) operaiPartecipano).compareTo(o.getOperaiPartecipano());
	}
Questa è la classe operaio

public class Operaio {
	
	private String codiceFiscale;
	private String nome;
	private String residenza;
	
	
	
	public Operaio (String codiceFiscale,String nome, String residenza)
	
	{
		this.codiceFiscale = codiceFiscale;
		this.nome = nome;
		this.residenza = residenza;
		
	}
	
	
	public String getCodiceFiscale ()
	
	{
		return codiceFiscale;
	}
	
	
	public String getNome ()
	
	{
		return nome;
		
	}
	
	public String getResidenza ()
	
	{
		return residenza;
		
	}

	
}
quando vado a fare il compareTo mi da un errore.

Quindi la mia domanda è: come faccio a prendere le n operazioni che hanno coinvolto piu operai ? Io avevo pensato di utilizzare il compareTo ma misa che sbaglio qualche cosa, magari qualcuno di voi mi puo dare una mano e spiegare come si usa.

Grazie anticipatamente

20 Risposte

  • Re: ArrayList e compareTo

    OpenSource ha scritto:


    quando vado a fare il compareTo mi da un errore.

    Quindi la mia domanda è: come faccio a prendere le n operazioni che hanno coinvolto piu operai ? Io avevo pensato di utilizzare il compareTo ma misa che sbaglio qualche cosa, magari qualcuno di voi mi puo dare una mano e spiegare come si usa.
    La classe Operaio va bene, tecnicamente è corretta.

    Per Operazioni invece la questione è diversa. La signature (firma) del compareTo è corretta. Ma nota che NON serve il SuppressWarnings e NON serve fare dei cast all'interno.

    L'espressione che ti è stata indicata cioè "le 3 Operazioni che hanno coinvolto piu operai" riguarda il numero di operai. Cioè l'ordinamento dovrà essere su questo criterio, ovvero se una operazione A ha maggior, minor o ugual numero di operai rispetto ad una operazione B. Quindi all'interno del compareTo non devi comparare le due liste così e basta ma devi comparare le lunghezze delle due liste!!
    E la lunghezza (size() ) è un int, quindi occhio, int non è un oggetto e NON ha un compareTo.

    Quindi:
    a) una serie di comparazioni banali con gli operatori > < ecc...
    oppure
    b) Da Java 7 il compare "statico" di Integer.


    P.S. sarebbe forse più corretto Operazione invece che Operazioni. Un oggetto modella una (non N) operazione con N operai.
  • Re: ArrayList e compareTo

    andbin ha scritto:


    OpenSource ha scritto:


    quando vado a fare il compareTo mi da un errore.

    Quindi la mia domanda è: come faccio a prendere le n operazioni che hanno coinvolto piu operai ? Io avevo pensato di utilizzare il compareTo ma misa che sbaglio qualche cosa, magari qualcuno di voi mi puo dare una mano e spiegare come si usa.
    La classe Operaio va bene, tecnicamente è corretta.

    Per Operazioni invece la questione è diversa. La signature (firma) del compareTo è corretta. Ma nota che NON serve il SuppressWarnings e NON serve fare dei cast all'interno.

    L'espressione che ti è stata indicata cioè "le 3 Operazioni che hanno coinvolto piu operai" riguarda il numero di operai. Cioè l'ordinamento dovrà essere su questo criterio, ovvero se una operazione A ha maggior, minor o ugual numero di operai rispetto ad una operazione B. Quindi all'interno del compareTo non devi comparare le due liste così e basta ma devi comparare le lunghezze delle due liste!!
    E la lunghezza (size() ) è un int, quindi occhio, int non è un oggetto e NON ha un compareTo.

    Quindi:
    a) una serie di comparazioni banali con gli operatori > < ecc...
    oppure
    b) Da Java 7 il compare "statico" di Integer.


    P.S. sarebbe forse più corretto Operazione invece che Operazioni. Un oggetto modella una (non N) operazione con N operai.
    Grazie mille andbin della risposta tempestiva, infatti io ho provato a fare il .size() ma come dici tu mi da un errore. Se mi potresti dare dei suggerimenti in merito anche con la scrittura di codice per capire, te ne sarei grato, grazie ancora per la disponibilita. Grazie del suggerimento per il nome della classe
  • Re: ArrayList e compareTo

    OpenSource ha scritto:


    mi potresti dare dei suggerimenti in merito anche con la scrittura di codice per capire
    Due opzioni, a) e b) le ho dette prima. Banalmente una catena di if (o con l'operatore condizionale) con il senso: Se size1 minore di size2 restituisci +1 altrimenti ecc...
    Nota: size1 è il size() della lista "this", size2 l'altra.

    Oppure vedi il compare di java.lang.Integer
  • Re: ArrayList e compareTo

    andbin ha scritto:


    OpenSource ha scritto:


    mi potresti dare dei suggerimenti in merito anche con la scrittura di codice per capire
    Due opzioni, a) e b) le ho dette prima. Banalmente una catena di if (o con l'operatore condizionale) con il senso: Se size1 minore di size2 restituisci +1 altrimenti ecc...
    Nota: size1 è il size() della lista "this", size2 l'altra.

    Oppure vedi il compare di java.lang.Integer

    Grazie ancora dell'aiuto, tu dici di fare in questo modo ?
    public int compareTo (Operazioni o)
    	
    	{
    		
    		if (this.getOperaiPartecipano().size() >  o.getOperaiPartecipano().size())
    			
    		{
    			return 1;
    			
    		}
    		else if (this.getOperaiPartecipano().size() < o.getOperaiPartecipano().size())
    			
    		{
    			return -1;
    		}
    		
    		return 0;
    		
    	}
  • Re: ArrayList e compareTo

    Esatto, la soluzione a) che dicevo è proprio questa ed è corretta. Però tieni presente che hai definito l'ordine in senso ascendente dei size.

    Vuoi prendere le ultime 3 operazioni con size in senso ascendente .... o le prime 3 in senso discendente??

    1 3 4 6 8 9
    o
    9 8 6 4 3 1

    Se è il secondo, devi "girare" il senso.
  • Re: ArrayList e compareTo

    andbin ha scritto:


    Esatto, la soluzione a) che dicevo è proprio questa ed è corretta. Però tieni presente che hai definito l'ordine in senso ascendente dei size.

    Vuoi prendere le ultime 3 operazioni con size in senso ascendente .... o le prime 3 in senso discendente??

    1 3 4 6 8 9
    o
    9 8 6 4 3 1

    Se è il secondo, devi "girare" il senso.
    Ciao e grazie ancora, si, voglio le prime 3 operazioni con più operai 'all'inizio' quindi decrescente.. Quindi devo cambiare i segni.
    La soluzione B che tu mi dicevi prima come si implementa ? Sarei molto curioso di vederla..
    Ti faccio sapere se funziona il tutto
  • Re: ArrayList e compareTo

    OpenSource ha scritto:


    La soluzione B che tu mi dicevi prima come si implementa ? Sarei molto curioso di vederla..
    Se guardi la documentazione javadoc di quel compare di Integer .... lo capisci.
  • Re: ArrayList e compareTo

    andbin ha scritto:


    OpenSource ha scritto:


    La soluzione B che tu mi dicevi prima come si implementa ? Sarei molto curioso di vederla..
    Se guardi la documentazione javadoc di quel compare di Integer .... lo capisci.

    Si ho visto, ma mi sorge un dubbio, dove c'è scritto integer x, integer y, dovrei mettere il size delle liste ?

    Dopo provo tutto e ti faccio sapere se va tutto ok per quanto riguarda il metodo A
  • Re: ArrayList e compareTo

    OpenSource ha scritto:


    Si ho visto, ma mi sorge un dubbio, dove c'è scritto integer x, integer y, dovrei mettere il size delle liste ?
    Sì ... guarda che quel compare fa esattamente quello che hai fatto tu. Solo che lo fa sicuramente con l'operatore condizionale ?: e non con gli if.
    Guarda ad esempio il sorgente del del OpenJDK (il compare nel JDK/JRE standard Oracle è uguale)
  • Re: ArrayList e compareTo

    andbin ha scritto:


    OpenSource ha scritto:


    Si ho visto, ma mi sorge un dubbio, dove c'è scritto integer x, integer y, dovrei mettere il size delle liste ?
    Sì ... guarda che quel compare fa esattamente quello che hai fatto tu. Solo che lo fa sicuramente con l'operatore condizionale ?: e non con gli if.
    Guarda ad esempio il sorgente del del OpenJDK (il compare nel JDK/JRE standard Oracle è uguale)

    Ciao, ho provato il metodo a "quello che ho scritto prima" ma non funziona cioe non ordina l'array in base alla dimensione delle persone presenti nella operazione, come mai ?

    Ho provato ad ordinare un ArrayList di tipo <persona> in base all'eta e funziona correttamente, quando lo vado a fare sull'ArrayList <operazioni> non mi ordina in base agli operai coinvolti
  • Re: ArrayList e compareTo

    OpenSource ha scritto:


    Ciao, ho provato il metodo a "quello che ho scritto prima" ma non funziona cioe non ordina l'array in base alla dimensione delle persone presenti nella operazione, come mai ?

    Ho provato ad ordinare un ArrayList di tipo <persona> in base all'eta e funziona correttamente, quando lo vado a fare sull'ArrayList <operazioni> non mi ordina in base agli operai coinvolti
    Puoi mostrare qualcosa di più? Fai vedere come è adesso la classe Operazioni. E anche, magari, il punto (anche solo un pezzetto) dove hai il ArrayList e lo ordini.
  • Re: ArrayList e compareTo

    andbin ha scritto:


    OpenSource ha scritto:


    Ciao, ho provato il metodo a "quello che ho scritto prima" ma non funziona cioe non ordina l'array in base alla dimensione delle persone presenti nella operazione, come mai ?

    Ho provato ad ordinare un ArrayList di tipo <persona> in base all'eta e funziona correttamente, quando lo vado a fare sull'ArrayList <operazioni> non mi ordina in base agli operai coinvolti
    Puoi mostrare qualcosa di più? Fai vedere come è adesso la classe Operazioni. E anche, magari, il punto (anche solo un pezzetto) dove hai il ArrayList e lo ordini.

    Certo, allora questa è la classe Operazioni
    import java.util.*;
    public class Operazioni implements Comparable <Operazioni> {
    	
    	private int data;
    	private String tipo;
    	public ArrayList <Operaio> operaiPartecipano = new ArrayList <Operaio> ();
    	
    	
    	public Operazioni (int data,String tipo, ArrayList <Operaio> operaiPartecipano)
    	
    	{
    		this.data = data;
    		this.tipo = tipo;
    		this.operaiPartecipano = new ArrayList <Operaio> (operaiPartecipano);
    		
    		
    		
    	}
    	
    	
    	
    	
    	public int getData ()
    	
    	{
    		return data;
    		
    	}
    	
    	public String getTipo ()
    	
    	{
    		return tipo;
    		
    	}
    	
    	
        public ArrayList<Operaio> getOperaiPartecipano ()
    	
    	{
    		return new ArrayList <Operaio> (operaiPartecipano);
    		
    		
    	}	
    		
    
    	
    	public int compareTo (Operazioni o)
    	
    	{
    		
    		if (this.getOperaiPartecipano().size() < o.getOperaiPartecipano().size())
    			
    		{
    			return 1;
    			
    		}
    		else if (this.getOperaiPartecipano().size() > o.getOperaiPartecipano().size())
    			
    		{
    			return -1;
    		}
    		
    		else return 0;
    		
    	}
    	
    
    
    }
    
    Poi all'interno della classe gestione azienda (dove gestisco tutti i metodi ecc) inserisco un metodo che ordina il mio ArrayList

    qui ho i vettori
    import java.util.*;
    public class GestioneAzienda {
    	
    	private ArrayList <Operaio> operai = new ArrayList <Operaio> ();
    	private ArrayList <Terreni> terreno = new ArrayList <Terreni> ();
    	private ArrayList <Operazioni> operazioni = new ArrayList <Operazioni> ();
    	
    Qui il costruttore della classe
    public GestioneAzienda ()
    	
    	{
    		terreno = new ArrayList <Terreni> ();
    		operai = new ArrayList <Operaio> ();
    		operazioni = new ArrayList <Operazioni> ();
    		
    		
    		
    		
    	}
    Questo il metodo dove lo ordino
    public void aggiorna ()
    	
    	{
    		Collections.sort(operazioni);
    		
    		
    		
    	}
    Se hai bisogno di altro materiale basta che mi dici
    Grazie ancora della disponibilità
  • Re: ArrayList e compareTo

    OpenSource ha scritto:


    Certo, allora questa è la classe Operazioni
    Allora: la classe Operazioni è tecnicamente corretta. Salvo il fatto che non hai ancora "girato" il senso della comparazione (che è tuttora per numero di operai in senso ascendente).
    Ci sono poi delle questioni di "design". Innanzitutto nel costruttore crei un nuovo ArrayList e nel getOperaiPartecipano() ne restituisci uno nuovo. Questo è BUONO, come concetto generale, se si vuole rendere la collezione interna intoccabile dall'esterno. Peccato che il campo della collezione sia "public" quindi chiunque ci può pasticciare ...
    Poi il fatto che getOperaiPartecipano() crei un nuovo ArrayList rende sicuramente meno performante il compareTo, visto che ad ogni comparazione ne vengono creati ben 4! Questo lo potresti evitare usando direttamente il campo.


    Per il resto ... è un po' oscuro. Nel senso che quello che hai postato dopo mostra delle classi con dei campi ma NON è chiaro cosa ci fai con il campo operai, non è chiaro come popoli questo ArrayList e come lo usi e non è nemmeno chiaro come/dove/quando popoli l'altro ArrayList operazioni.
  • Re: ArrayList e compareTo

    andbin ha scritto:


    OpenSource ha scritto:


    Certo, allora questa è la classe Operazioni
    Allora: la classe Operazioni è tecnicamente corretta. Salvo il fatto che non hai ancora "girato" il senso della comparazione (che è tuttora per numero di operai in senso ascendente).
    Ci sono poi delle questioni di "design". Innanzitutto nel costruttore crei un nuovo ArrayList e nel getOperaiPartecipano() ne restituisci uno nuovo. Questo è BUONO, come concetto generale, se si vuole rendere la collezione interna intoccabile dall'esterno. Peccato che il campo della collezione sia "public" quindi chiunque ci può pasticciare ...
    Poi il fatto che getOperaiPartecipano() crei un nuovo ArrayList rende sicuramente meno performante il compareTo, visto che ad ogni comparazione ne vengono creati ben 4! Questo lo potresti evitare usando direttamente il campo.


    Per il resto ... è un po' oscuro. Nel senso che quello che hai postato dopo mostra delle classi con dei campi ma NON è chiaro cosa ci fai con il campo operai, non è chiaro come popoli questo ArrayList e come lo usi e non è nemmeno chiaro come/dove/quando popoli l'altro ArrayList operazioni.
    Allora ti spiego meglio: Ho una classe chiamata gestioneAzienda dove viene gestito tutto il progetto, quindi all'interno ci sono tutti i metodi necesseri al funzionamento del programma es (un metodo per aggiungere gli operai, un altro per le operazioni, un altro per farmi dare le operazioni dove sono presenti piu operai, un metodo che stampa tutti gli operai presenti ecc. Quando devo popolare la lista Operaio vado nel main richiamo il metodo es aggiungiOperaio (che è presente nella classe gestioneAzienda) e come paramentro gli passo un oggetto di tipo operaio, e cosi via per le altre liste. Per quanto riguarda la performance al momento non mi interessa perche sto cercando di capire alcuni concetti (comunque grazie per avermelo fatto notare ). Sempre in questa classe ad esempio se gli chiedo di ordinare in base all'eta degli operai funziona (utilizzando il metodo "A") quando lo utilizzo sulle liste invece no.... Spero di essere stato esaustiente altrimenti ti posto tutto il codice della classe e cerco di spiegare ancora meglio.. Grazie ancora per il tempo che mi stai concedendo
Devi accedere o registrarti per scrivere nel forum
20 risposte