views:

330

answers:

4

I have a Hashtable of type Hashtable

I've loaded several strings as keys, one of which is "ABCD"

However, later when I go to look up "ABCD", the Hashtable returns null instead of the associated object. Further the keyset contains "ABCD", but a request to containsKey("ABCD") returns false.

Is this because String objects are inherently different objects?

If so, what is the write way to store information in a Hashtable if I want to use Strings as keys?

 public class Field {
        private String name;
        private DataType dataType;

        public Field(String name, DataType dataType) {
            this.name = name;
            this.dataType = dataType;
        }

        public String getName() {
            return name;
        }

        public DataType getDataType() {
            return dataType;
        }

        public String toString() {
            return name;
        }
    }

public class Record {
        private Hashtable<String, Data> content; 

        public Record(Field[] fieldList) {
            this.fieldList = fieldList;     
            content = new Hashtable<String, Data>();

            System.out.println(fieldList.length);

            for(Field f : fieldList) {          
                content.put(f.getName(), new Data());
            }
        }

        public void add(String field, String s) {
                    // ERROR OCCURS HERE IN THIS METHOD !!!

            System.out.println(field);

            for(String ss : content.keySet()) {
                System.out.print(" [ " + ss + " ] ");
            }
            System.out.println();

            System.out.println(content.containsKey(field));     
            System.out.println(content.get(field));

            content.get(field).add(s);
        }
}



public class Data {

    private Vector<String> lines;
    private int index;

    public Data() {
        lines = new Vector<String>();
        index = 0;
    }

    public void add(String s) {
        System.out.println("adding");
        lines.add(s);
    }

    public String nextLine() {
        try {
            return lines.elementAt(index++);
        } catch (ArrayIndexOutOfBoundsException aioobe) {
            return null;
        }
    }
}
A: 

Hashtable is a Java 1.0 data structure. I wonder why you're not using a Map?

If java.lang.String is the key type, I'd say you're being hosed by something else that's impossible to guess without posting code.

duffymo
I tried to use the map to and got the same result.
Kirk
If you have the same issue with `HashTable` as you did with `HashMap` then you may as well go back to using `HashMap`
barrowc
+7  A: 

Works for me!

import java.util.Hashtable;

public class StrMap {
    public static void main(String[] args) {
        Hashtable<String,Object> map = new Hashtable<String,Object>();
        map.put("ABCD", "value");
        System.err.println(map.containsKey("ABCD"));
    }
}

Yo have probably made some other error. Reduce the problem to the smallest complete compilable program that still demonstrates the problem. You'll probably find the problem straight away. If you don't, at least you will have a question that we can answer.

(Also Map and HashMap is that way to go. Hashtable is useful if you are using a pre-Java 2 API (Java 2 is comfortably over a decade old now!).)

Tom Hawtin - tackline
+1: Agree that the code looks fine. Perhaps this is an issue with invisible whitespace, similar Unicode characters or something such that the table contains a key that *appears* to be the same but is a separate sequence of characters. Also yes, definitely use a `Map` for this!
Andrzej Doyle
There was whitespace for some reason and I was having a hard time seeing it where it was... silly me.
Kirk
+1. i did check my code/logic. I was calling hashTbl.contains() instead of hashTbl.containsKey() ! why there are three: contains() containsKey() and containsValue(). i see there is need for two only.
Ankit Jain
@Ankit Jain `containsKey` and `containsValue` are from `Map`. `contains` is for compatibility with pre-1.2 Java.
Tom Hawtin - tackline
A: 

It's hard to pinpoint the root cause without an SSCCE from your side.

At least, the common causes are:

  1. You're not using the Hashtable you think you're using. System.out.println() it to verify.
  2. The String is actually in a different case, e.g. "ABcD" instead of "ABCD".
  3. The String is surrounded with some whitespace which you needs to trim() first.

That said (and unrelated to the actual problem), I strongly recommend to use the improved HashMap instead of the legacy Hashtable. Here's a Sun tutorial about maps.

BalusC
Again, I started with the HashMap
Kirk
I said, *unrelated* to the **actual problem**. Follow the three common causes. Check the outcome of `System.out.println(content)` before using it, check if the String is in right case and it doesn't contain surrounding whitespace. They have to be an **exact** match.
BalusC
A: 

Can you also post the exact output you get from the following method when field is "ABCD"?

   public void add(String field, String s) {
                // ERROR OCCURS HERE IN THIS METHOD !!!

        System.out.println(field);

        for(String ss : content.keySet()) {
            System.out.print(" [ " + ss + " ] ");
        }
        System.out.println();

        System.out.println(content.containsKey(field));     
        System.out.println(content.get(field));

        content.get(field).add(s);
    }
richs