Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Map returns null for a present key

I'm having a very unusual problem.
Basically, I'm trying to get the value associated with a key from a Map of Strings to Strings.
I know that the key I'm using is present; I'm using the same string I used to put it in!

I've print statements all over my code, and this is case I have...
Here is my dictionary characterDictionary

{thusChar=∴, spaceChar= , plusChar=+, equalsIndent=#, multiplyChar=×, equalsChar==, newlineChar=\n, divideChar=÷, subjectChar=:, variableIndent=@}

The very last key "variableIndent" is the trouble!
Here's the code...

System.out.println  (   characterDictionary.get("variableIndent") );

which inappropriately outputs: null

I have checked, double checked and triple checked my code.
There is absolutely no difference between the key "variableIndent" and the string argument of characterDictionary.get("variableIndent"), yet it's behaving as if this key was not present.

I can absolutely guarantee this key is present, and that the two strings are identical.
All the other elements (the ones I've checked; about 3 so far) of the dictionary are retrieved as normal. Why is "variableIndent" with it's "@" value playing up?

You might notice the dictionary contains non ASCII characters, like "thusChar". Could this be related?

Thanks
(This seems like a very simple and trivial problem, as if I've made some pitifully silly mistake, but yet I just can't solve it!)

EDIT:

Okay, this HAS to be something about encoding.
I took the string key from the dictionary and compared it to my get argument.
When printed, they are identical, but java says they are not equal.
The key string came from a UTF-8 encoded text file, whilst the argument string came from a java Eclipse literal.
The characters are identical however.
What is the issue, and how can I resolve it?

Thanks!

EDIT:

Hmmm, here's what's actually happening behind the scenes.
I have a UTF-8 text file which contains the following content...

variableIndent,@
equalsIndent,#
spaceChar, 
newlineChar,\n
multiplyChar,×
divideChar,÷
plusChar,+
equalsChar,=
subjectChar,:
thusChar,∴

I 'load' this file by reading in each line of the file as an ArrayList<String> element, by passing the directory of the file:

private static ArrayList<String> readLinesFile(String ResourceFile)  {
    ArrayList<String> Lines = new ArrayList<String>();
        try{
            InputStream fstream = FileManager.class.getResourceAsStream(ResourceFile);
            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
            String strLine;
            while ((strLine = br.readLine()) != null)  {
                Lines.add(strLine);  } 
            in.close();  }
        catch (Exception e)  {
            System.out.println("Error: " + e.getMessage());  } 
        return Lines;  }

Everything is fine up to here.
I then pass this ArrayList into a function that splits up each element by the "," character (using a function from a personal package; It is definitely not the issue), and adds the first part as a key to the second in the new dictionary.

private static Map<String, String> generateBaseUnits_Characters_Prefixes(ArrayList<String> FileContent)  {
    Map<String, String> BaseUnitsCache = new HashMap<String, String>();
    ArrayList<String> currentLine;
    for (int i=0; i<FileContent.size(); i++)  {
        currentLine = MiscellaneousFunctions.splitString(FileContent.get(i), ",");
        BaseUnitsCache.put(currentLine.get(0), currentLine.get(1)); }
    return BaseUnitsCache;  }

and this produces the dictionary that is causing all the trouble.
I have a set of Key Literals that correspond to the character names in the text files, which I use to access the dictionary in the program.

public static String variableIndentKey = "variableIndent";
public static String equalsIndentKey = "equalsIndent";
public static String spaceCharKey = "spaceChar";  
public static String newlineCharKey = "newlineChar";
public static String multiplyCharKey = "multiplyChar";
public static String divideCharKey = "divideChar";  
public static String plusCharKey = "plusChar";
public static String equalsCharKey = "equalsChar";  
public static String subjectCharKey = "subjectChar";
public static String thusCharKey = "thusChar";

HERE'S THE PROBLEM:

The top line of the textfile 'screws up' in the dictionary. It is added to the dictionary and appears correctly amongst the keySet and the printed format of the dictionary, but trying to access it returns "null".
(In this case, it's variableIndent. If I put variableIndent somewhere else in the text file, equalsIndent screws up, etc)

What's going on!?
Do I have a dodgy function?!
They've worked well for everything else.

Thanks!

like image 840
Anti Earth Avatar asked Aug 11 '12 07:08

Anti Earth


2 Answers

change you UTF-8 text file which contains the key and value to UTF-8 without BOM. There are three bytes(UTF-8 BOM 0xEF,0xBB,0xBF before "variableIndent") see http://en.wikipedia.org/wiki/Byte_order_mark

like image 71
andy Avatar answered Sep 20 '22 20:09

andy


If you are afraid of encoding issues (that seems to be the problem here), you have to make sure your project's encoding is set to UTF-8. To check it, go to Project menu, and choose Properties. It may be required to change text file encoding from Inherited from container to Oher: UTF-8

like image 30
dantuch Avatar answered Sep 16 '22 20:09

dantuch