Visualizzazione dei risultati da 1 a 2 su 2
  1. #1
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328

    [Java] HashMap: strano comportamento del metodo containsKey()

    Forse sto lavorando troppo e forse mi sto perdendo in un bel bicchiere d'acqua, ma questo comportamento da parte del metodo containsKey() di HashMap non me lo riesco a spiegare.

    Vediamo la situazione. Ho costruito la seguente classe, che intendo usare come chiave all'interno della HashMap:
    codice:
    public class KeyDay implements Comparable {
       private String id;
       private String internalID;
    
       public KeyDay(String id) {
          this.id = id;
          createInternalID();
       }
    
       private void createInternalID() {
          internalID = id.substring(6, 10) + id.substring(3, 5) + id.substring(0, 2);
       }
    
       public String getInternalID() { return internalID; }
       public String toString() { return id; }
    
       public int compareTo(Object obj) {
          KeyDay k = (KeyDay) obj;
          return internalID.compareTo( k.getInternalID() );
       }
    
       public boolean equals(Object obj) {
          KeyDay kd = (KeyDay) obj;
          return internalID.equals( kd.getInternalID() );
       }
    
       public static void main(String[] args) {
          KeyDay k1 = new KeyDay("12/05/2008");
          KeyDay k2 = new KeyDay("12/05/2008");
          System.out.println("Equals: " + k1.equals(k2) + " -- " + k2.equals(k1));
          System.out.println("CompareTo: " + k1.compareTo(k2) + " -- " + k2.compareTo(k1));
       }
    }
    Il main l'ho aggiunto solo a scopo di test, per verificare che la classe abbia il comportamento che desidero, ed in fatti così è... questo è il suo output:
    codice:
    Equals: true -- true
    CompareTo: 0 -- 0
    Eppure, appena tento di utilizzare questa classe in una HashMap, il comportamento non è coerente con quanto imposto dal metodo equals() da me ridefinito. Questo è l'esempio:
    codice:
    import java.util.*;
    
    public class Tester {
       public static void main(String[] args) {
          // Questi saranno i miei valori chiave
          String[] date = {"12/05/2008", "12/05/2008", "12/05/2008"};
    
          HashMap hm = new HashMap();
          for(int i=0; i<date.length; i++) {
             KeyDay day = new KeyDay( date[i] );
             if ( hm.containsKey(day) ) {
                System.out.println("Trovata la data nel calderone");
             } else {
                System.out.println("Data " + day + " non trovata nel calderone... la inserisco");
                hm.put(day, "Inserita");
             }
          }
    
          Iterator it = hm.keySet().iterator();
          while( it.hasNext() ) System.out.println( it.next() );
       }
    }
    L'esempio è stupido, ma questo è il suo output:
    codice:
    Data 12/05/2008 non trovata nel calderone... la inserisco
    Data 12/05/2008 non trovata nel calderone... la inserisco
    Data 12/05/2008 non trovata nel calderone... la inserisco
    12/05/2008
    12/05/2008
    12/05/2008
    Ora, stando alla documentazione del metodo containsKey() dell'interfaccia Map (la documentazione di HashMap dice che tale metodo è specificato all'interno di tale interfaccia, dato che la implementa)
    Returns true if this map contains a mapping for the specified key. More formally, returns true if and only if this map contains at a mapping for a key k such that (key==null ? k==null : key.equals(k)). (There can be at most one such mapping.)
    La chiave non è nulla, quindi il valore restituito dovrebbe essere quello di
    codice:
    key.equals(k)
    che per la definizione precedente (vedi esecuzione della classe KeyDay) è coerente...

    Allora mi domando: dove sto sbagliando?


    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

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Mi sono risposto da solo... manca l'implementazione di hashCode()!!!
    Devo ricordarmi di andare a vedere più spesso il sorgente delle classi del core Java che uso...


    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.