Visualizzazione dei risultati da 1 a 10 su 10

Hybrid View

  1. #1

    Controllo delle chiavi in una HashMap

    Ragazzi ho ancora problemi con un altro esercizio

    Dovevo gestire una Biblioteca, utilizzando una struttura dati Mappa, ma non era specificato quale implementazione.

    Le possibili scelte erano: LinkedHashMap, TreeMap e HashMap, e ho scelto di provare per prima con la HashMap.

    Vi posto soltanto la parte di codice che mi dà problemi.

    Questa è la classe Libro, che poi sarà utilizzata come CHIAVE per la mappa:
    codice:
    public class Libro{
    	
    	private String autore;
    	private String titolo;
    	
    	
    	public Libro(String autore, String titolo)
    	{
    		this.autore=autore;
    		this.titolo=titolo;
    	}
    
    
    	public String getAutore() {
    		return autore;
    	}
    
    
    	public String getTitolo() {
    		return titolo;
    	}
    	
    	public String toString()
    	{
    		return ("Autore: " + autore + "\n" + "Titolo: " + titolo + "\n");
    	}
    }


    Questa è la classe InfoLibro, che poi verrà usata come VALORE per la mappa:
    codice:
    public class InfoLibro {
    	
    	private int copieLibro;
    	private int copieInPrestito;
    	
    	
    	public InfoLibro (int copieLibro)
    	{
    		this.copieLibro=copieLibro;
    		copieInPrestito=0;
    	}
    
    
    	public int getCopieLibro() {
    		return copieLibro;
    	}
    
    
    	public void setCopieLibro(int copieLibro) {
    		this.copieLibro = copieLibro;
    	}
    
    
    	public int getCopieInPrestito() {
    		return copieInPrestito;
    	}
    
    
    	public void setCopieInPrestito(int copieInPrestito) {
    		this.copieInPrestito = copieInPrestito;
    	}
    	
    	
    	public String toString()
    	{
    		return ("Copie Libro: " + copieLibro + "\n" + "Copie in prestito: " + copieInPrestito + "\n");
    	}

    Questa è la classe Libreria (ho allegato solo una parte del codice), che sarà il mio Buffer condiviso tra Produttore-Consumatore:
    codice:
    import java.util.HashMap;
    
    
    public class Libreria {
    
    	private HashMap<Libro, InfoLibro> libreria;
    	
    	
    	
    	public Libreria ()
    	{
    		libreria = new HashMap<Libro, InfoLibro>();
    	}
    	
    	
    	public void inserisciLibro(Libro l, int copie)
    	{
    		if (libreria.containsKey(l))   //se il libro è già presente nella libreria
    		{
    			InfoLibro temp = libreria.get(l);
    			temp.setCopieLibro(temp.getCopieLibro() + copie);
    		}
    		
    		else  //libro non presente nella libreria
    		{
    			libreria.put(l, new InfoLibro(copie));
    		}		
    	}

    Questo è il MainTest_1:
    codice:
    public class TestLibreria {
    
    	
    	public static void main(String[] args) {
    		
    		
    		Libreria libreria;		
    		
    		libreria = new Libreria();
    		
    		Libro l1, l2, l3;
    		
    		
    		l1 = new Libro("Autore 1", "Titolo 1");
    		l2 = new Libro("Autore 2", "Titolo 2");
    		l3 = l1;
    		
    		
    		libreria.inserisciLibro(l1, 3);
    		libreria.inserisciLibro(l2, 2);
    		libreria.inserisciLibro(l1, 10);
    		libreria.inserisciLibro(l3, 10);
    
                    System.out.println(libreria.toString());

    Questo è MainTest_2:
    codice:
    public class TestLibreria {
    
    	
    	public static void main(String[] args) {
    		
    		
    		Libreria libreria;
    		
    		libreria = new Libreria();
    		
    		libreria.inserisciLibro(new Libro("Autore 1", "Titolo 1"), 3);
    		libreria.inserisciLibro( new Libro("Autore 2", "Titolo 2"), 2);
    		libreria.inserisciLibro( new Libro("Autore 1", "Titolo 1"), 10);
    		libreria.inserisciLibro( new Libro("Autore 2", "Titolo 2"), 10);
    		
    		System.out.println(libreria.toString());
    Se eseguo il MainTest_1 come output ottengo:
    codice:
    Autore: Prova_Autore 1
    Titolo: Prova_Titolo 1
    Copie Libro: 23
    Copie in prestito: 0
    
    Autore: Prova_Autore 2
    Titolo: Prova_Titolo 2
    Copie Libro: 2
    Copie in prestito: 0
    Se eseguo il MainTest_2 come output ottengo:
    codice:
    Autore: Prova_Autore 1
    Titolo: Prova_Titolo 1
    Copie Libro: 3
    Copie in prestito: 0
    
    Autore: Prova_Autore 2
    Titolo: Prova_Titolo 2
    Copie Libro: 2
    Copie in prestito: 0
    
    Autore: Prova_Autore 1
    Titolo: Prova_Titolo 1
    Copie Libro: 10
    Copie in prestito: 0
    
    Autore: Prova_Autore 2
    Titolo: Prova_Titolo 2
    Copie Libro: 10
    Copie in prestito: 0

    Praticamente nel test 1 le chiavi uguali vengono riconosciute (cioè i Libri) mentre nel test 2 no; infatti nel test 1 vengono aggiornate le copie dei libri disponibili invece nel test 2 anche se cerco di inserire libri già presenti non vengono riconosciuti come libri già esistenti nella biblioteca e quindi non vengono aggiornati i numeri delle copie ma vengono aggiunti nuovamente nella HashMap come se fossero nuovi libri.

    L'unica differenza è che nel test 1 al metodo inserisciLibro della Libreria passiamo un riferimento di un oggetto Libro creato già, mentre nel secondo test passiamo un riferimento di un oggetto Libro creato al momento; quindi anche se creiamo due oggetti con lo stesso Autore e Titolo, essi hanno riferimento diversi.

    Quindi ho ipotizzato che la put della HashMap non controlla il contenuto dell'oggetto Libro ma si limita soltanto a confrontare i riferimenti della chiavi.

    E' corretta questa ipotesi?
    Grazie

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da JavaForEver112 Visualizza il messaggio
    - due oggetti equals(uguali) devono avere lo stesso codice hash.
    Sì.

    Quote Originariamente inviata da JavaForEver112 Visualizza il messaggio
    - due oggetti con lo stesso hashcode non devono essere equals
    No, o perlomeno è detto molto male.
    Se due oggetti hanno lo stesso hash code, possono essere O non essere uguali. Non è infatti questo lo scenario importante.

    Lo scenario davvero importante e fondamentale è quello detto all'inizio. In più se due oggetti sono "diversi" (per equals() ), allora possono avere o no lo stesso hash code ma se producono hash code differenti allora è meglio e più performante (per le hash-table).

    Infine, cosa che non hai citato ma fa parte del "corollario": se due oggetti hanno hash code diversi, allora i due oggetti DEVONO essere diversi per equals().

    Quote Originariamente inviata da JavaForEver112 Visualizza il messaggio
    Se rispetti le suddette regole eviterai il problema delle collisioni
    Salvo casi "particolari" (es. Integer contiene un int, il hash code è quel int e quindi sono tutti distinti), difficilmente si possono evitare "collisioni".
    L'obiettivo di hashCode() NON è quello di evitare collisioni. Queste ci possono potenzialmente sempre essere e non sono il grosso problema. L'obiettivo è quello di produrre hash code il più possibilmente distinti e ben distribuiti.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    E anche qui, come nell'altra.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.