Eliminare duplicati ArrayList

di Anonimizzato19908 il
19 risposte
Ciao a tutti, ho un problema con un esercizio. Avrei bisogno di eliminare tutti i duplicati da una lista di oggetti, ma non riesco a venirne a capo.
import java.util.ArrayList;

public class EsempioArrayList
{
public static void main(String[] args)
{

ArrayList<Quadrato> ListaQuadrati = new ArrayList<Quadrato>();

for(int x = 0 ;x < 1000; x++)
{
int lato = (int) (Math.random()*21) +1;
Quadrato myQuadrato = new Quadrato(lato);
ListaQuadrati.add(myQuadrato);
}
System.out.println(ListaQuadrati);
}
}

questo è l 'array. Help

19 Risposte

  • Soluzione banale: crei una nuova lista e prima di inserire l'elemento, controlli se non e' gia' presente tra gli elementi che SEGUONO l'elemento in considerazione nella lista di partenza.
  • migliorabile ha scritto:


    Soluzione banale: crei una nuova lista e prima di inserire l'elemento, controlli se non e' gia' presente tra gli elementi che SEGUONO l'elemento in considerazione nella lista di partenza.
    Scusami ma non ho capito. Io da quello che ho capito devo utilizzare Hashset per rimuovere un duplicato in una lista, ma non capisco come utilizzarlo. Ho provato creando un ciclo for, mettendo un condizionale e poi il metodo remove, ma non va.
  • AleX3mE ha scritto:


    Avrei bisogno di eliminare tutti i duplicati da una lista di oggetti, ma non riesco a venirne a capo.
    Se vuoi rimuovere gli oggetti in più che hanno lo stesso lato, innanzitutto sarebbe utile usare una collezione temporanea, un "set" (es. HashSet). Il punto è che ci sono almeno due soluzioni:
    1) un HashSet<Integer> che contiene i lati (int -> Integer)
    2) un HashSet<Quadrato> che contiene gli oggetti Quadrato ma SOLO se in Quadrato hai ridefinito opportunamente equals/hashCode per stabilire la "uguaglianza" tra due oggetti diversi Quadrato basandosi appunto sul lato.

    Poi per rimuovere dalla lista, sarebbe meglio usare l'iteratore esplicitamente (non il for-each) poiché puoi usare il suo remove(). Poi indipendentemente dalla soluzione 1) o 2), semplicemente: c'è già nel set quel lato/quadrato? Se sì, rimuovi il Quadrato, se no inserisci lato/quadrato nel set.
  • No, non ho utilizzato equals, il codice della lista è quello messo nel post.
    devo basarmi sul lato, quindi utlizzare HashSet<integer>? sai dove posso approfondire questo argomento, perchè su internet non si trova molto.
  • AleX3mE ha scritto:


    devo basarmi sul lato, quindi utlizzare HashSet<integer>?
    Se Quadrato NON ridefinisce equals/hashCode non ha senso HashSet<Quadrato>. Pertanto l'unica è appunto HashSet<Integer> che contiene direttamente i lati.

    AleX3mE ha scritto:


    sai dove posso approfondire questo argomento, perchè su internet non si trova molto.
    Il tutorial ufficiale Oracle, la documentazione javadoc in particolare di HashSet e .... sicuramente tanto altro che trovi su blog/libri/articoli ecc...
  • Quindi:
    HashSet<Quadrato> hashSet = new HashSet<>(); // hashset istanziato.

    ora devo ciclarlo? però con che condizioni?
  • AleX3mE ha scritto:


    Quindi:
    HashSet<Quadrato> hashSet = new HashSet<>(); // hashset istanziato.
    No, se Quadrato NON ridefinisce equals/hashCode.

    HashSet<Integer>

    AleX3mE ha scritto:


    ora devo ciclarlo? però con che condizioni?
    Prima ho detto che conviene iterare usando l'iteratore esplicitamente (perché iterando PUOI rimuovere con il suo remove() ).
    Quindi tira fuori il Iterator dal tuo ArrayList<Quadrato> e poi itera con la coppia hasNext() / next() (e poi remove() quando sai di dover rimuovere)
  • HashSet<Integer> hashSet = new HashSet<>();
    while (hashSet.iterator().hasNext())
    {
    System.out.println(hashSet.iterator().next().toString());
    }

    in questo modo?
  • AleX3mE ha scritto:


    HashSet<Integer> hashSet = new HashSet<>();
    while (hashSet.iterator().hasNext())
    {
    System.out.println(hashSet.iterator().next().toString());
    }

    in questo modo?
    No, il Iterator lo devi ottenere UNA volta sola. E comunque devi iterare sul tuo ArrayList che contiene i 1000 quadrati, NON sul HashSet !
  • Puoi spiegarti meglio magari facendomi un esempio generico
  • AleX3mE ha scritto:


    Puoi spiegarti meglio
    Ogni volta che invochi iterator() su una collezione, ottieni un NUOVO oggetto Iterator. Quindi è ovvio che NON puoi prenderlo nuovo ad ogni hasNext/next!! Pertanti: invochi iterator(), assegni l'iteratore ad una variabile Iterator<Quadrato> e poi usi questa variabile.
  • Potresti farmi un esempio in codice, altrimenti cosi mi è un po confuso
  • AleX3mE ha scritto:


    Potresti farmi un esempio in codice, altrimenti cosi mi è un po confuso
    Immagina di avere una lista di 1000 oggetti Persona, alcuni li vuoi rimuovere dalla lista in base a certe condizioni.
    ArrayList<Persona> persone = ....
    
    Iterator<Persona> personeIter = persone.iterator();
    
    while (personeIter.hasNext()) {
        Persona persona = personeIter.next();
    
        // usa persona
    }
    Poi nel ciclo qualcosa es.
    if ( .... se da rimuovere .... ) {
        personeIter.remove();
    }
    Nota: il remove() del Iterator ... NON della collezione (la collezione NON la puoi modificare strutturalmene con i suoi metodi mentri iteri).
  • E nel mio caso, avendo già creato la lista di mille oggetti, come proseguo...perchè con questo esempio non ci capisco molto.
    
    public class EsempioArrayList
    {
    	public static void main(String[] args)
    		{
    			
    			ArrayList<Quadrato> ListaQuadrati = new ArrayList<Quadrato>();       //Lista 
    			
    			for(int x = 0 ;x < 1000; x++)            
    			{
    				int lato = (int) (Math.random()*21) +1;     
    				Quadrato myQuadrato = new Quadrato(lato);   
    				ListaQuadrati.add(myQuadrato);           
    			}	
    				
    			System.out.println(ListaQuadrati);     
    Questa è la mia lista, ora come proseguo? Grazie mille per la pazienza che hai.
Devi accedere o registrarti per scrivere nel forum
19 risposte