|
|
|
![]() |
|
Strumenti |
![]() |
#41 |
Senior Member
Iscritto dal: Nov 2006
Messaggi: 355
|
Ciao ho un'altra cosa da chiederti. Ho un ArrayList contenente oggetti pesona
vorrei ordinarlo per cognome, con il metodo Collection.sort() ma non va! come mai? me lo puoi postare? grazie
__________________
Ho concluso felicemente molte transizioni su altri forum e ben 60 feedback positivi su eBay--- Ho concluso felicemete con : royaleagle, SUPERALEX, bambà, bartmad, blade86. |
![]() |
![]() |
![]() |
#42 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Supponendo che l'oggetto Persona abbia un metodo getCognome(), l'ordinamento di un ArrayList di Persona potrebbe essere ottenuto con:
Codice:
Comparator<Persona> comparatore = new Comparator<Persona>() { public int compare(Persona a, Persona b) { return a.getCognome().compareTo(b.getCognome()); } }; Collections.sort(lista, comparatore);
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#43 |
Senior Member
Iscritto dal: Nov 2006
Messaggi: 355
|
la classe comparator si deve fare per forza? se è si come???
__________________
Ho concluso felicemente molte transizioni su altri forum e ben 60 feedback positivi su eBay--- Ho concluso felicemete con : royaleagle, SUPERALEX, bambà, bartmad, blade86. |
![]() |
![]() |
![]() |
#44 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Nell'esempio, comparatore è un'istanza di una classe interna anonima che concretizza l'interfaccia Comparator<Persona>.
L'alternativa è dotare la classe Persona di un ordine naturale. Per farlo devi modificare Persona in modo tale che concretizzi l'interfaccia Comparable<Persona>. Ciò richiede che la classe Persona sia dotata di un metodo di questo tipo: Codice:
public int compare(Persona that) { return this.getCognome().compareTo(that.getCognome()); } Collections.sort(lista); dove lista è l'ArrayList<Persona>.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#45 |
Senior Member
Iscritto dal: Nov 2006
Messaggi: 355
|
Ecco qua! ho fatto sia la classe Persona(ovvero Name) che la classe Ordina .
Perchè non funziona..........c'è sicuro qulache errore, puoi controllare? Codice Name: import java.util.Scanner; class Name { public Name(String nome,String cognome){ this.nome = nome; this.cognome= cognome; } public String getNome(){ return nome; } public String getCognome(){ return cognome; } public static Name read(Scanner in) throws Exception{ if(!in.hasNext()) return null; return new Name(in.nextLine(), in.nextLine()); } public int compareTo(Name that) { return this.getCognome().compareTo(that.getCognome()); } private String nome, cognome; } e qui il codice Ordina: import java.io.FileReader; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Ordina { public Ordina(String file)throws Exception{ Scanner in =new Scanner(new FileReader(file)); ArrayList<Name> a = new ArrayList<Name>(); Name n = Name.read(in); while(n!=null){ a.add(n); n = Name.read(in); } in.close(); n.compareTo(n); Collections.sort(a); } }
__________________
Ho concluso felicemente molte transizioni su altri forum e ben 60 feedback positivi su eBay--- Ho concluso felicemete con : royaleagle, SUPERALEX, bambà, bartmad, blade86. |
![]() |
![]() |
![]() |
#46 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Nel codice che hai, hai anche dichiarato:
class Name implements Comparable<Name> { ?
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#47 |
Senior Member
Iscritto dal: Nov 2006
Messaggi: 355
|
si
__________________
Ho concluso felicemente molte transizioni su altri forum e ben 60 feedback positivi su eBay--- Ho concluso felicemete con : royaleagle, SUPERALEX, bambà, bartmad, blade86. |
![]() |
![]() |
![]() |
#48 |
Senior Member
Iscritto dal: Nov 2006
Messaggi: 355
|
e se hanno cognomi uguali e nomi diversi
__________________
Ho concluso felicemente molte transizioni su altri forum e ben 60 feedback positivi su eBay--- Ho concluso felicemete con : royaleagle, SUPERALEX, bambà, bartmad, blade86. |
![]() |
![]() |
![]() |
#49 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se Name è un comparable<Name> allora quel Collections.sort(a) non può che ordinare i nomi. In che senso non va? Non te li ordina? Sarebbe un bel mistero.
Cognomi uguali e nomi diversi. Non so se sia corretto dal punto di vista semantico ma potresti dire che nel caso in cui i cognomi sono uguali allora ordini rispetto al nome. Codice:
public int compareTo(Name that) { int value = this.getCognome().compareTo(that.getCognome()); if(value == 0) { value = this.getNome().compareTo(that.getNome()); } return value; }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#50 |
Senior Member
Iscritto dal: Nov 2006
Messaggi: 355
|
Scusa se ti assillo!!! MI potresti fare una panoramica sulla classe HashSet con i relativi metodi e se puoi un esempio??? grazie
__________________
Ho concluso felicemente molte transizioni su altri forum e ben 60 feedback positivi su eBay--- Ho concluso felicemete con : royaleagle, SUPERALEX, bambà, bartmad, blade86. |
![]() |
![]() |
![]() |
#51 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
HashSet è un Set, cioè un insieme che non contiene duplicati.
Dato un oggetto pippo, il suo duplicato è l'oggetto ciccio se ciccio.equals(pippo) è true. HashSet usa una hashmap per conservare i valori. Per il programmatore significa che gli oggetti inseriti devono avere codici hash diversi se sono diversi e uguali se sono uguali. Il codice hash di un oggetto è il valore (int) restituito dal suo metodo hashCode(). HashSet ha tre metodi di interesse. add, remove e contains. Add aggiunge un elemento se non è gia stato inserito. remove rimuove un elemento già inserito. contains restituisce true se l'insieme contiene l'elemento in argomento. Fine dell'hashset. Ricorda che il valore restituito dal metodo hashCode di un oggetto Java dovrebbe seguire le sorti del metodo equals. Vale a dire che due oggetti a e b per cui a.equals(b) è true dovrebbero anche avere uguali codici hash, cioè a.hashCode() == b.hashCode(). Prendiamo ad esempio una Persona. Codice:
public class Persona { private String nome; private String cognome; public String getNome() { return nome; } public String getCognome() { return cognome; } } HashSet<Persona> set = new HashSet<Persona>(); Persona gianni = new Persona("gianni", "rossi"); Persona mario = new Persona("mario", "verdi"); set.add(gianni); set.add(mario); Qui set.contains(gianni); vale true e set.contains(mario) anche. La faccenda funziona perchè Persona riceve i metodi equals ed hashCode definiti in Object. I due metodi di Object sono, da un punto di vista orientato agli oggetti, immondi. Dichiarano che un oggetto è uguale ad un altro se risiede allo stesso indirizzo di memoria. Se prendiamo la nostra Persona appare quasi evidente l'uguaglianza per indirizzo sia a dir poco bizzarra: una Persona possiede due caratteri, il nome ed il cognome, ma sarebbe uguale ad un altra in virtù di un terzo valore, l'indirizzo di memoria, del quale poco sappiamo, ancor meno vogliamo sapere e soprattutto nulla possiamo fare. Se intendiamo usare la capacità di Persona di dichiarare la sua uguaglianza con un'altro oggetto, e per HashSet questo è necessario, allora dobbiamo anche stabilire un significato di uguaglianza che sia coerente con la rappresentazione di una Persona. Possiamo scegliere se usare il nome, il cognome od entrambi ma il minimo che ci si può aspettare è che una Persona sia uguale ad un'altra se le loro definizioni coincidano, in tutto o in parte. Noi prendiamo tutto quanto: nome e cognome. Stabiliamo che due persone sono uguali se i loro nomi ed i loro cognomi coincidano. La storia è simile a quanto hai già fatto per "compareTo" ma stavolta si tratta di ridefinire i metodi equals e hashCode. Il metodo equals restituirà true se questa persona e quell'altra abbiano lo stesso nome e lo stesso cognome: Codice:
public class Persona { private String nome; private String cognome; public Persona(String nome, String cognome) { this.nome = nome; this.cognome = cognome; } public String getNome() { return nome; } public String getCognome() { return cognome; } public boolean equals(Object o) { //se "o" è una Persona if(o instanceof Persona) { Persona that = (Persona)o; //restituisce true se il nome di questa persona è uguale //al nome di quella e il cognome di questa persona è //uguale al cognome di quella return this.getNome().equals(that.getNome()) && this.getCognome().equals(that.getCognome()); } else {//se o non è una persona... return false; } } public int hashCode() { ...vediamo dopo; } } Nel caso di Persona, quindi, il nostro numero intero deve essere uguale per ogni coppia di stringhe (nome, cognome) uguali, perchè sono queste due stringhe che determinano l'uguaglianza tra due Persona. Una possibile versione del metodo hashCode per Persona è questa: Codice:
public int hashCode() { long hashNome = getNome().hashCode(); long hashCognome = getCognome().hashCode(); long longHash = (hashNome << 32) + hashCognome; return new Long(longHash).hashCode(); } 1. prende il codice hash (intero, 32 bit) del nome. 2. prende il codice hash (intero, 32 bit) del cognome. 3. crea un numero a 64 bit composto da [nome][cognome] 4. restituisce il codice hash di quel numero a 64 bit. Il metodo sfrutta la proprietà del metodo hashCode di String che dichiara di restituire numeri uguali per sequenze di caratteri uguali e il comportamento predefinito del metodo hashCode di Long, che restituisce a sua volta int uguali per long uguali. La faccenda va presa cum grano salis. Il codice hash è un intero a 32 bit. Due codici hash di due stringhe combinati fanni un intero a 64 bit. Riducendo questi 64 bit a 32 è ovvio che sussista la possibilità di collisioni. Cioè è possibile che Persone dal nome diverso restituiscano codici hash uguali. Se il numero di persone è tuttavia limitato (relativamente, qualche centinaio di milioni) le probabilità che si verifichi una collisione sono piuttosto basse. Nel caso in cui il numero di persone sia elevato (miliardi) allora dovrai definire un codice hash più ampio. Essendo il codice hash a 32 bit usato per definizioni dalla mappa di HashSet, dovrai anche creare un nuovo HashSet. La Persona vista all'inizio e la Persona con i metodi hashCode ed equals sovrascritti si comportano in modo diverso quando sono usati in un HashSet. Con la prima persona: HashSet<Persona> set = new HashSet<Persona>(); set.add(new Persona("gianni", "rossi")); set.contains(new Persona("gianni", "rossi")); <-- FALSO Falso perchè istanze diverse sono allocate in aree di memoria diverse. Ma con la seconda Persona e gli stessi enunciati: HashSet<Persona> set = new HashSet<Persona>(); set.add(new Persona("gianni", "rossi")); set.contains(new Persona("gianni", "rossi")); <---VERO Vero perchè noi, tramite i metodi hashCode ed equals, abbiano stabilito che due persone sono uguali quanto abbiano nome e cognome uguali. Per dubbi, domande, perplessità...sai dove trovarmi.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#52 |
Senior Member
Iscritto dal: Nov 2006
Messaggi: 355
|
Grazie!!!! Come si fa a ordinare un HashSet???
__________________
Ho concluso felicemente molte transizioni su altri forum e ben 60 feedback positivi su eBay--- Ho concluso felicemete con : royaleagle, SUPERALEX, bambà, bartmad, blade86. |
![]() |
![]() |
![]() |
#53 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
L'HashSet non è ordinabile.
Puoi usare un TreeSet al posto dell'HashSet oppure creare una vista ordinata del contenuto dell'HashSet. Per la seconda: ArrayList<X> lista = new ArrayList<X>(hashSet); Collections.sort(lista); La scelta è una questione di compromessi. Le operazioni aggiungi, rimuovi e contiene in un HashSet sono eseguite più rapidamente delle corrispondenti operazioni su un TreeSet. D'altro canto, ordinare un HashSet richiede la creazione di un nuovo elenco di riferimenti mentre un TreeSet è ordinato per natura. La scelta migliore è il frutto di un'analisi statistica del comportamento dell'applicazione. Se l'applicazione esegue per lo più aggiunte rimozioni e verifiche di contenimento allora l'HashSet è preferibile al TreeSet. D'altro canto è possibile che il maggiore spazio in memoria richiesto per la creazione di una vista ordinata sull'HashSet non sia sopportabile. Se l'operazione prevalente dipende dall'ordinamento la maggiore onerosità in accesso al TreeSet può essere positivamente bilanciata dal fatto che il suo contenuto è costantemente ordinato. Tecnicamente sono numeri. Calcoli quanti accessi e quanti ordinamenti farai, moltiplichi per il costo di accesso e ordinamento, sia in termini di memoria che in termini di rapidità di esecuzione, poi valuti quale soluzione sia obiettivamente migliore.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:36.