简体   繁体   中英

Will I get bugs if I use a string for a hashtable key in java?

I want to use a hashtable to uniquely link immutable string IDs to mutable objects. If I have two strings of the same characters, will Java interpret them as different keys to the hash table? I know that Strings are objects, so two strings might not have the same reference.

In other words, if I do ...

myHashTable.add("A" , ObjectA)
String myReference = "A" 
myHashTable.add(myReference, ObjectB) // I am not sure how java will interpret this
myHashTable.get("A") //returns A
myHashTable.get(myReference) //returns B
myReference.equals("A") //returns true

Can I safely use strings as keys to the hashtable (meaning that strings made up of the same characters will return the same value)

The String.hashCode() method is based only on the content of the string, not the object identity. So yes, this is safe.

HashMap and HashSet depend on the keys' hashCode and equals method. String 's equals method compares string character by character and its hashCode methods is consistent with that. So, you can use two String s that have the same characters but are != reference-wise and they will hash to the same value in a HashMap .

The javadoc explains all this in clear language. You should give it a read.

 public V get(Object key) 

Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key. More formally, if this map contains a mapping from a key k to a value v such that (key==null ? k==null : key.equals(k)) , then this method returns v; otherwise it returns null. (There can be at most one such mapping.)

Caveat: IdentityHashMap breaks that contract.

References are not compared; the equals method is used (unless null , which is permitted in HashMap but not Hashtable ). So different string objects whose values are both "A" will be treated as the same key.

See http://ideone.com/V6Y7b

import java.util.*;
class Test {
    private static String key1 = "ABC";

    public static void main(String[] args) {
        Map<String, Integer> m = new HashMap<String, Integer>();
        String key2 = "A" + "\u0042" + "c".toUpperCase();
        m.put(key1, 4);
        m.put(key2, 100);
        System.out.println(key1 == key2);
        System.out.println(m.size());
    }
}

Output:

false
1

From API Hash table use the,

To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method and the equals method.

String has hashCode() and equals() method implemented and the implementation depends on the characters present in the string.

So, strings made up of the same characters will return the same value .

With an IdentityHashMap you would get different results for map.get("a") and map.get(new String("a")) , but that class is clearly documented as violating the general contract of maps:

This class is not a general-purpose Map implementation! While this class implements the Map interface, it intentionally violates Map's general contract, which mandates the use of the equals method when comparing objects. This class is designed for use only in the rare cases wherein reference-equality semantics are required.

For normal Map implementations there is no problem with using string keys.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM