簡體   English   中英

Java Map為當前鍵返回null

[英]Java Map returns null for a present key

我有一個非常不尋常的問題。
基本上,我正在嘗試從字符串映射到字符串獲取與鍵相關聯的值。
我知道我正在使用的鑰匙存在; 我使用的是與之相同的字符串!

我在我的代碼中打印了一些語句,這就是我的情況......
這是我的字典characterDictionary

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

最后一個關鍵“variableIndent”就是麻煩!
這是代碼......

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

不恰當地輸出: null

我已檢查,雙重檢查並三重檢查我的代碼。
“variableIndent”characterDictionary.get("variableIndent")的字符串參數之間完全沒有區別,但它的行為就好像這個鍵不存在一樣。

我絕對可以保證這個密鑰存在,並且兩個字符串是相同的。
所有其他元素(我檢查過的那些;到目前為止大約3個)都是正常檢索的。 為什么“variableIndent”的“@”值正在播放?

您可能會注意到該字典包含非ASCII字符,例如“soChar”。 這有關系嗎?

謝謝
(這似乎是一個非常簡單和微不足道的問題,好像我犯了一些可憐的愚蠢錯誤,但我卻無法解決它!)

編輯:

好的,這是關於編碼的東西。
我從字典中取出字符串鍵並將其與我的get參數進行比較。
打印時,它們是相同的,但java說它們並不相同。
鍵字符串來自UTF-8編碼的文本文件,而參數字符串來自java Eclipse文字。
但是字符是相同的。
問題是什么,我該如何解決?

謝謝!

編輯:

嗯,這就是幕后實際發生的事情。
我有一個UTF-8文本文件,其中包含以下內容......

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

我通過傳遞文件的目錄,通過讀取文件的每一行作為ArrayList<String>元素'加載'此文件:

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;  }

這里的一切都很好。
然后我將這個ArrayList傳遞給一個函數,該函數用“,”字符分割每個元素(使用個人包中的函數;絕對不是問題),並將第一部分作為第二部分添加到新的第二部分中字典。

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;  }

這會產生導致所有麻煩的字典。
我有一組與文本文件中的字符名稱相對應的Key Literals,我用它來訪問程序中的字典。

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";

這是問題所在:

文本文件的頂行在字典中“搞砸了”。 它被添加到字典中並正確顯示在keySet和字典的打印格式中,但嘗試訪問它會返回“null”。
(在這種情況下,它是variableIndent。如果我將variableIndent放在文本文件中的其他位置,則equalsIndent擰緊等)

這是怎么回事!?
我有狡猾的功能嗎?!
他們對其他一切都很好。

謝謝!

將包含密鑰和值的UTF-8文本文件更改為不帶BOM的UTF-8。 在“variableIndent”之前有三個字節(UTF-8 BOM 0xEF,0xBB,0xBF),請參閱http://en.wikipedia.org/wiki/Byte_order_mark

如果您害怕編碼問題(這似乎是問題),您必須確保項目的編碼設置為UTF-8 要進行檢查,請轉到“ 項目”菜單,然后選擇“ 屬性” 可能需要將文本文件編碼Inherited from container更改為Oher: UTF-8

我建議你在調試器中查看你的代碼。 我懷疑地圖不是你想象的那樣。

String data = "{thusChar=∴, spaceChar= , plusChar=+, equalsIndent=#, multiplyChar=×, equalsChar==, newlineChar=\\n, divideChar=÷, subjectChar=:, variableIndent=@}";
Map<String, String> map = new LinkedHashMap<String, String>();
for (String keyValue : data.substring(1, data.length() - 1).split(", ")) {
    String[] parts = keyValue.split("=", 2);
    map.put(parts[0], parts[1]);
}
System.out.println("variableIndent is " + map.get("variableIndent"));

版畫

variableIndent is @

你能試一下嗎

for(String key: map.keySet())
   System.out.println("'"+key+"'= "+map.get(key));

嗯嘗試這段代碼,讓我們知道輸出

for (String key : characterDictionary.keySet() ) {
System.out.println(key);
}

for ( String value :  characterDictionary.values() ) {
System.out.println(value);
}

PS:可能想要更改鍵和值的類型。

如果您認為這是一個編碼問題,那么請嘗試使用以下方法來比較實際內容,而不管其外觀如何。

使用getBytes()從兩個字符串中獲取所有字節(來自地圖的鍵,以及代碼中的字符串),並打印

  1. 字節數組的長度
  2. 每個字節為整數

然后使用getChars()獲取來自Strings或charAt()所有字符以讀取每個char,並打印

  1. 每個char為整數。

在這兩個檢查之間,您應該能夠弄清楚兩個字符串在字節級別上是如何不同的。 保存文件的字符集是什么?

編輯

我懷疑你使用DataInputStream會導致讀取字節的問題。

InputStream fstream = FileManager.class.getResourceAsStream(ResourceFile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));

DataInputStream的Java文檔說:“數據輸入流允許應用程序以與機器無關的方式從底層輸入流中讀取原始Java數據類型。應用程序使用數據輸出流來寫入數據,以后可以通過數據輸入讀取流。” 你不是在這里讀取DataOutputStream,只是一個常規文件。 此外,您已經有一個InputStream用於InputStreamReader。 將您的代碼更改為:

InputStream fstream = FileManager.class.getResourceAsStream(ResourceFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

編輯2

另一件值得做的事情,因為你的文本文件中的字符串長3個字節,正在改變它

BaseUnitsCache.put(currentLine.get(0), currentLine.get(1));

BaseUnitsCache.put(currentLine.get(0).trim(), currentLine.get(1).trim());

試試這種方式......

Map<String, String> map = new LinkedHashMap<String, String>();


for (Map.Entry<String, String> mp : map.entrySet()){


  System.out.println("Key: "+mp.key()+"::"+"Value: "+mp.value());


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM