【发布时间】:2013-12-31 02:11:19
【问题描述】:
我有一个HashMap<String, String>,它保存了图像的文件名和显示名称。我逐行读取文件并将键和值添加到 HashMap。
BufferedReader reader;
String line;
String[] lineSplit;
HashMap<String, String> imenaZnaki = new HashMap<String, String>();
try {
reader = new BufferedReader(new InputStreamReader(am.open("znaki_imena.txt"), "UTF-8"));
line = reader.readLine();
while (line != null) {
lineSplit = line.split("->");
imenaZnaki.put(lineSplit[0], lineSplit[1]);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
一切都按预期工作,除了第一个添加的条目,.get(key) 返回 null 并且 .containsKey(key) 返回 false。所有其他键/值都可以正常工作并正确存储在 HashMap 中。
编辑:
这根本没有意义......在我将内容添加到 HashMap 后,我运行了 MagicMan 提供的代码来检查所有条目是否都在 HashMap 内
for(String key: imenaZnaki.keySet()) {
System.out.println("KEY: " + key + " VALUE: " + imenaZnaki.get(key));
}
如果我将 CTRL + F 用于“nevar_andrej”,它会显示 4 个输出,这是正确的。但是,如果我搜索“nevar_andrej”(带有空格),它只会显示其中的 3 个,这是错误的,因为第一个会丢失。所以我的猜测是,文件的第一行中有一些东西会引起混淆。所以我添加了一个虚拟/假的第一行(bla_bla->Bla bla)并且它有效,但这是一个讨厌的解决方法。
这是我用 UTF-8 http://pastebin.com/6A4r4jm6 编码的全文文件
【问题讨论】:
-
在调试器中单步执行。
get和containsKey极不太可能存在存储Strings 的错误。 -
使用 HashMap.keySet() 转储映射中的键集。你确定你的钥匙不在里面吗?很有可能这是某种编码错误 - 我猜你测试的“nevar_andrejev ...”字符串的版本与文件中的实际内容略有不同。您可以尝试在十六进制阅读器中查看您的源代码和文本文件,以比较字符串并确保它们逐字节相同。
-
@user2339071 - java 中的数组不会增长。您可以创建一个更大的新数组,但它们不会增长。此时,您会注意到 lineSplit 来自 String.split() 函数,该函数每次调用时都会分配一个新数组。
-
"Unicode" 在这里表示 UTF-16 ("Unicode" 不是一种编码 - 它是一个为字形和字形修饰符分配值的系统;它没有提到如何将这些值存储在磁盘上或在内存中); Microsoft 有时可能很愚蠢。 C# 在内部将值存储为 UTF-16,因此当您复制内容以放入文本文件和代码时,可能会出现问题,而且碰巧它使用 UTF-16 时可以正常工作。 UTF-8 和 UTF-16 都完全能够代表整个 unicode 代码空间。
-
在意识到我对编码的了解真的很差之后,我偶然发现了一篇很棒的文章,标题是:每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最小值(没有借口!)@987654322 @