1 interfacce e polimorfismo sandro pedrazzini approfondimento interfacce e polimorfismo
TRANSCRIPT
![Page 1: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/1.jpg)
1 Interfacce e polimorfismoSandro Pedrazzini
Approfondimento
Interfacce e polimorfismo
Approfondimento
Interfacce e polimorfismo
![Page 2: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/2.jpg)
2 Interfacce e polimorfismoSandro Pedrazzini
MotivazioneMotivazione
Importanza del polimorfismo nell’utilizzo dei pattern e, piùIn generale, nella programmazione OO
Ruolo degli elementi “interface”
Disaccoppiamento degli elementi
Programmazione generica
Estensione di funzionalità esistente
![Page 3: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/3.jpg)
3 Interfacce e polimorfismoSandro Pedrazzini
InterfaceInterface
• Separazione del concetto di interfaccia da quello di classe
• Più classi possono realizzare la stessa interfaccia
Sci
calcolaImporto(…)
Carving
calcolaImporto(…)
Bambini
calcolaImporto(…)
Normale
calcolaImporto(…)
![Page 4: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/4.jpg)
4 Interfacce e polimorfismoSandro Pedrazzini
Esempio 1: genericità con l’interfaccia IconEsempio 1: genericità con l’interfaccia Icon
• Java mette a disposizione il metodo showMessageDialog(...) per mostrare un dialogo in interfaccia
JOptionPane.showMessageDialog(null,"Hello World");
![Page 5: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/5.jpg)
5 Interfacce e polimorfismoSandro Pedrazzini
Scelta dell’icona (1)Scelta dell’icona (1)
• Esistono altri overloading del metodo showMessageDialog(...). Ne scegliamo uno che ci permetta di specificare cosa mostrare come immagine nel messaggio.
class JOptionPane extends JComponent implements Accessible{ ... public static void showMessageDialog( Component parentComponent, Object message, String title, int messageType, Icon icon) {...}
}
![Page 6: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/6.jpg)
6 Interfacce e polimorfismoSandro Pedrazzini
Scelta dell’icona (2)Scelta dell’icona (2)
JOptionPane.showMessageDialog(null,"Hello World”,“message dialog”,JOptionPane.INFORMATION_MESSAGE,new ImageIcon(“lampadina.gif”));
![Page 7: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/7.jpg)
7 Interfacce e polimorfismoSandro Pedrazzini
Nuova sceltaNuova scelta
• Supponiamo ora di voler visualizzare nel messaggio una forma grafica senza dover generare precedentemente un file contenente l’immagine.
• Visto che showMessageDialog(...) accetta un elemento di tipo Icon, non siamo obbligati a passare ImageIcon, ma possiamo fornire un oggetto di qualsiasi classe che realizzi l’interfaccia Icon.
![Page 8: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/8.jpg)
8 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Icon (1)Interfaccia Icon (1)
public interface Icon{ int getIconWidth(); int getIconHeight(); void paintIcon( Component c, Graphics g, int x, int y);}
![Page 9: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/9.jpg)
9 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Icon (2)Interfaccia Icon (2)
• Un’interfaccia non contiene una realizzazione di funzionalità. Specifica semplicemente un insieme di metodi.
• Qualsiasi classe che implementi l’interfaccia Icon ha due responsabilità:
– Fornire la dimensione dell’icona
– Disegnare l’icona.
![Page 10: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/10.jpg)
10 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Icon (3)Interfaccia Icon (3)
• Il parametro Component di paintIcon() rappresenta il componente grafico che deve contenere l’immagine. Da questo è possibile ottenere alcune proprietà, come il colore dello sfondo, il font, ecc.
• È quindi possibile disegnare l’immagine nell’area grafica (Graphics) in modo che si adatti al contesto in cui viene disegnata.
![Page 11: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/11.jpg)
11 Interfacce e polimorfismoSandro Pedrazzini
Implementazione (1)Implementazione (1)
• Realizziamo una classe WorldIcon che implementa Icon.
• La classe disegna un cerchio rappresentante il mondo.
• Un oggetto di questa classe potrà essere passato al metodo showMessageDialog(), che non ha bisogno di conoscere la classe WorldIcon. Gli basta sapere che si comporta come (implementa) Icon.
![Page 12: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/12.jpg)
12 Interfacce e polimorfismoSandro Pedrazzini
Implementazione (2)Implementazione (2)
Icon
paintIcon(…)
WorldIcon
paintIcon(…)
ImageIcon
paintIcon(…)
![Page 13: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/13.jpg)
13 Interfacce e polimorfismoSandro Pedrazzini
Implementazione (2)Implementazione (2)
public class WorldIcon implements Icon{ private int fSize;
public WorldIcon(int size){ fSize = size; }
public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D)g; Ellipse2D.Double world = new Ellipse2D.Double(x,y,fSize, fSize); g2.setColor(Color.BLUE); g2.fill(world); }
public int getIconWidth() { return fSize; }
public int getIconHeight() { return fSize; }}
![Page 14: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/14.jpg)
14 Interfacce e polimorfismoSandro Pedrazzini
UtilizzoUtilizzo
JOptionPane.showMessageDialog( null,"Hello World", "message dialog", JOptionPane.INFORMATION_MESSAGE, new WorldIcon(60));
![Page 15: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/15.jpg)
15 Interfacce e polimorfismoSandro Pedrazzini
Considerazioni (1)Considerazioni (1)
• Chi realizza il metodo showMessageDialog() non ha nessuna idea di quale tipo di icona verrà passata.
• Le classi utilizzate per realizzare l’icona possono essere completamente diverse. L’unica cosa in comune consiste nell’implementare l’interfaccia Icon.
• Solo quando viene chiamato in showMessageDialog() un metodo di Icon, l’interprete Java cerca di identificare il vero tipo dell’oggetto.
![Page 16: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/16.jpg)
16 Interfacce e polimorfismoSandro Pedrazzini
Considerazioni (2)Considerazioni (2)
• Il polimorfismo è caratterizzato proprio da questa capacità di selezionare il metodo appropriato per un certo oggetto.
• Un utilizzo importante del polimorfismo consiste nel fornire meccanismi che si comportino come accoppiamento rilassato.
• Nel nostro caso: il metodo showMessageDialog() non ha bisogno di nessuna informazione di come WorldIcon elabori l’immagine. È solamente interessato alle chiamate all’interfaccia Icon. Non esiste nessun accoppiamento tra JOptionPane e WorldIcon.
![Page 17: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/17.jpg)
17 Interfacce e polimorfismoSandro Pedrazzini
Considerazioni (3)Considerazioni (3)
• Quando utilizziamo la classe di una libreria di terzi, prima viene implementata la libreria, poi il nostro programma principale che la utilizza.
• Quando creiamo una nostra sottoclasse da usare in modo polimorfico, il programma principale che la utilizza può essere stato implementato da terzi ben prima che noi mettiamo a disposizione la nostra funzionalità specifica
=> Principio del “framework”
![Page 18: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/18.jpg)
18 Interfacce e polimorfismoSandro Pedrazzini
Esempio 2: ComparableEsempio 2: Comparable
• Altro esempio di codice generico con l’utilizzo del polimorfismo
• Metodo statico sort() della classe Collections, in grado di ordinare una lista qualsiasi.
List list = ...;Collections.sort(list);
![Page 19: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/19.jpg)
19 Interfacce e polimorfismoSandro Pedrazzini
Comparable (1)Comparable (1)
• I singoli oggetti della lista possono appartenere a una classe qualsiasi, a patto che implementi l’interfaccia Comparable.
public interface Comparable<T>{ int compareTo(T other);}
• La chiamata a compareTo() restituisce un valore negativo se l’oggetto invocante precede l’oggetto parametro, zero se i due oggetti sono uguali e un valore positivo
![Page 20: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/20.jpg)
20 Interfacce e polimorfismoSandro Pedrazzini
Comparable (2)Comparable (2)
• Come mai tutti gli oggetti devono essere di tipo Comparable?
• Perché l’algoritmo di sort, chiamando compareTo() riesce a decidere gli spostamenti degli oggetti, senza dover conoscere il loro vero tipo.
Comparable<...> object1 = ...;if (object1.compareTo(object2) > 0){ sposta object1 rispetto a object2}
![Page 21: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/21.jpg)
21 Interfacce e polimorfismoSandro Pedrazzini
Comparable (3)Comparable (3)
Esempio 1: String realizza Comparable
List<String> countries = new ArrayList<String>();countries.add(“Switzerland);countries.add(“Belgium”);countries.add(“Germany”);
Collections.sort(countries);...
![Page 22: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/22.jpg)
22 Interfacce e polimorfismoSandro Pedrazzini
Comparable (4)Comparable (4)Esempio 2: Realizzazione di una nuova classe
public class Country implements Comparable<Country> { private String fName; private double fArea;
public Country(String name, double area){ fName = name; fArea = area; }
public String getName() { return fName; }
public double getArea() { return fArea; }
• Criterio di ordinamento: dimensione della superficie del territorio
public int compareTo(Country other) { if (fArea < other.getArea()){ return -1; } if (fArea > other.getArea()){ return 1; } return 0; }}
![Page 23: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/23.jpg)
23 Interfacce e polimorfismoSandro Pedrazzini
Comparable (5)Comparable (5)
• Utilizzo della classe Country, con ordinamento secondo la grandezza in km2
public class CountryTry { public static void main(String[] args) { List<Country> countries = new ArrayList<Country>(); countries.add(new Country("Belgium",77000)); countries.add(new Country("Switzerland",41000)); countries.add(new Country("Uruguay",440000)); ... Collections.sort(countries);
for (Country country : countries){ System.out.println(country.getName() + " " + country.getArea()); } }}
![Page 24: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/24.jpg)
24 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Comparator (1)Interfaccia Comparator (1)
• Se ora volessimo ordinare le stesse nazioni dell’esempio 2 in base al nome, invece che in base alla superficie, dovremmo ridefinire il metodo compareTo().
• Oltre che essere scomodo, ci obbligherebbe a definire sottoclassi unicamente per distinguere diversi metodi compareTo() (modifica del design per scopi che con il design nulla hanno a che vedere)
![Page 25: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/25.jpg)
25 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Comparator (2)Interfaccia Comparator (2)
• Soluzione: utilizzo di un overloading di sort(), che accetta come secondo parametro un oggetto Comparator
• Gli oggetti presenti in List vengono ordinati in base all’ordinamento definito in Comparator.
class Collections { ... public static void sort(List<T> list, Comparator<? super T> c) { ... }}
![Page 26: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/26.jpg)
26 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Comparator (3)Interfaccia Comparator (3)
• La lista List può ora contenere oggetti di qualsiasi tipo.
• Non è più necessario che appartengano a classi che implementino un’interfaccia particolare.
public class Country { private String fName; private double fArea;
public Country(String name, double area){ fName = name; fArea = area; }
public String getName() { return fName; }
public double getArea() { return fArea; }}
![Page 27: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/27.jpg)
27 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Comparator (4)Interfaccia Comparator (4)
public class ComparatorByName implements Comparator<Country> { public int compare(Country country1, Country country2) { String name1 = country1.getName(); String name2 = country2.getName();
return name1.compareTo(name2); //implementato in String }}
![Page 28: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/28.jpg)
28 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Comparator (5)Interfaccia Comparator (5)
public class ComparatorByArea implements Comparator<Country> { public int compare(Country country1, Country country2) { String area1 = country1.getArea(); String area2 = country2.getArea();
if (area1 < area2){ return -1; } if (area1 > area2){ return 1; }
return 0; }}
![Page 29: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/29.jpg)
29 Interfacce e polimorfismoSandro Pedrazzini
Interfaccia Comparator (6)Interfaccia Comparator (6)
• Utilizzo di ComparatorByName
public class CountryTry2 { public static void main(String[] args) { List<Country> countries = new ArrayList<Country>(); countries.add(new Country("Switzerland", 15000)); countries.add(new Country("Uruguay", 170000)); countries.add(new Country("Belgium", 30000)); ... Collections.sort(countries, new ComparatorByName());
for (Country country : countries) { System.out.println(country.getName() + " " + country.getArea()); } }}
![Page 30: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/30.jpg)
30 Interfacce e polimorfismoSandro Pedrazzini
Overriding di equals() e hashCode() (1)Overriding di equals() e hashCode() (1)
• Una comune sorgente di errore in applicazioni Java consiste nel dimenticare di riscrivere il metodo hashCode() ogni volta che si riscrive equals().
• Il metodo hashCode() viene usato quando si ha a che fare con elementi di Collection, come liste e tabelle hash.
![Page 31: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/31.jpg)
31 Interfacce e polimorfismoSandro Pedrazzini
Overriding di equals() e hashCode() (2)Overriding di equals() e hashCode() (2)
• Il contratto, come specificato in Object, prevede
1. hashCode() deve restituire sempre lo stesso valore se chiamato più volte sullo stesso oggetto (non necessariamente lo stesso tra un’esecuzione e l’altra)
2. Se due oggetti sono uguali rispetto a equals(), anche i loro metodi hasCode() devono restituire lo stesso risultato
3. Se due oggetti sono diversi, rispetto a equals(), non è detto che hashCode() debba restituire risultati diversi. Se però si fa in modo che anche le hashCode() restituiscono risultati diversi, anche la performance di tabelle hash migliora
![Page 32: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/32.jpg)
32 Interfacce e polimorfismoSandro Pedrazzini
Oggetti uguali, stesso hashCodeOggetti uguali, stesso hashCode
• L’errore più frequente capita con il punto 2: oggetti uguali devono avere lo stesso valore di hash
– Capita infatti che due oggetti siano uguali dal punto di vista logico (overriding di equals()), ma dal loro valore di hash sono diversi
– Il metodo hashCode() viene ereditato da Object, che assegna un hashCode diverso ad ogni nuovo oggetto (tipicamente convertendo l’indirizzo di allocazione in un int, anche se non dev’essere necessariamente così)
![Page 33: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/33.jpg)
33 Interfacce e polimorfismoSandro Pedrazzini
Esempio (1)Esempio (1)public class Country { private String fName; private double fArea;
public Country(String name, double area){ fName = name; fArea = area; }
public String getName() { return fName; }
public double getArea() { return fArea; }
public boolean equals(Object o) { if (o == this){ return true; } if (!o instanceof Country) { return false; } Country county = (Country)o; return country.getName().equals(fName) && country.getArea() == fArea; }}
![Page 34: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/34.jpg)
34 Interfacce e polimorfismoSandro Pedrazzini
Esempio (2)Esempio (2)
• Supponiamo ora di voler usare questa classe con HashMap
Map<Country, Integer> population = new HashMap<Country, Integer>();population.put(new Country(“Switzerland”, 15000), 7000000);
Ci si aspetterebbe che un’espressione del genere restituisca il valore di 7 milioni, invece restituisce null
population.get(new Country(“Switzerland”, 15000));
gli oggetti coinvolti sono 2 e il fatto di aver omesso l’implementazione di hashCode() causa un diverso valore per istanze diverse
![Page 35: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/35.jpg)
35 Interfacce e polimorfismoSandro Pedrazzini
Esempio (3)Esempio (3)
• Bisogna allora provvedere a fornire un hashCode che sia uguale per istanze equals
• Variante semplice, ma da non usare !!
public int hashCode() {
return 150;
}
![Page 36: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/36.jpg)
36 Interfacce e polimorfismoSandro Pedrazzini
Esempio (4)Esempio (4)
• Un codice fisso è “legale” perché assicura che oggetti uguali abbiano lo stesso hashCode
• Non è una buona soluzione, perché fa in modo che TUTTI gli oggetti abbiano hashCode uguale.
• In questo modo tutti gli oggetti in una hash table avrebbero stessa chiave, facendo degenerare la tabella in una lista semplice, con i costi che ne derivano
![Page 37: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/37.jpg)
37 Interfacce e polimorfismoSandro Pedrazzini
hashCode (1)hashCode (1)
• Una buona funzione di hash tende a produrre valori diversi di hash per oggetti diversi
• Ci sono varie ricette su come generare valori di hashCode
• Alcuni elementi da considerare:– Cercare di considerare tutti i campi significativi usati in equals()
– Tralasciare i campi ridondanti (calcolati da altri campi)
– Se un campo è un array, trattarlo come se ogni elemento fosse un campo separato
![Page 38: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/38.jpg)
38 Interfacce e polimorfismoSandro Pedrazzini
hashCode (2)hashCode (2)
• Esempio tratto da Bloch, Effective Java
– Registra una costante iniziale nella variabile risultato (esempio: 17)– Per ogni campo genera un valore intero
» Per ogni elemento di tipo scalare, usare il valore effettivo» byte, char, short, int => (int) f» float => Float.floatToIntBits(f)» long => (int) (f^(f >>> 32) (xor con shift a destra di 4 byte)» Per riferimenti a oggetti che in equals() sono usati attraverso il loro equals(), usare il loro valore di
hashCode()– Combinare tutti i valori ottenuti in questo modo:
risultato = 31 * risultato + valore
Verificare che a istanze uguali corrispondano valori uguali
Il valore 31 è scelto perché numero primo. Un vantaggio di 31 consiste nel fatto che la moltiplicazione può essere rimpiazzata da uno shift e sottrazione, più performanti.
31 * i == (i << 5) -i
Moderne VM eseguono automaticamente questo tipo di ottimizzazione
![Page 39: 1 Interfacce e polimorfismo Sandro Pedrazzini Approfondimento Interfacce e polimorfismo](https://reader035.vdocuments.site/reader035/viewer/2022081507/5542eb68497959361e8d3cd6/html5/thumbnails/39.jpg)
39 Interfacce e polimorfismoSandro Pedrazzini
EsempioEsempiopublic class Country { private String fName; private double fArea;
...
public boolean equals(Object o) { if (o == this){ return true; } if (!o instanceof Country) { return false; } Country county = (Country)o; return country.getName().equals(fName) && country.getArea() == fArea; }
public int hashCode() { int result = 17; result = 31 * result + fName.hashCode(); long areaCode = Double.doubleToLongBits(fArea); result = 31 * result + (int)(areaCode ^(areaCode >>> 32)); return result; }}