Java 文件的第一个字是';hashmap.containskey会将t识别为文件中稍后出现的其他单词
我正在使用mapreduce构建一个反向索引(这方面的知识不需要帮助解决我的问题)。为此,我在map函数中使用了一个hashmap,其中包含一个单词在文件中的出现情况,以及该单词在文件中的位置 输出如下所示:Java 文件的第一个字是';hashmap.containskey会将t识别为文件中稍后出现的其他单词,java,dictionary,hashmap,containskey,Java,Dictionary,Hashmap,Containskey,我正在使用mapreduce构建一个反向索引(这方面的知识不需要帮助解决我的问题)。为此,我在map函数中使用了一个hashmap,其中包含一个单词在文件中的出现情况,以及该单词在文件中的位置 输出如下所示: bart [Bart_the_Murderer.txt.gz{10, 83, 117, ..., 2356}, Bart_the_Murderer.txt.gz{1}] bart [Bart_the_Murderer.txt.gz{1, 10, 83, 117, ..., 2
bart [Bart_the_Murderer.txt.gz{10, 83, 117, ..., 2356}, Bart_the_Murderer.txt.gz{1}]
bart [Bart_the_Murderer.txt.gz{1, 10, 83, 117, ..., 2356}]
但应该是这样的:
bart [Bart_the_Murderer.txt.gz{10, 83, 117, ..., 2356}, Bart_the_Murderer.txt.gz{1}]
bart [Bart_the_Murderer.txt.gz{1, 10, 83, 117, ..., 2356}]
我构建hashmap的代码:
if (!map.containsKey(tokenForMap)) {
if(filePos == 1 || filePos == 10 || filePos == 83)
LOG.info("no key contained for: " + tokenForMap);
inputStringForMap = INPUTFILE.toString();
inputStringForMap = inputStringForMap + "{" + filePos + "}";
map.put(tokenForMap, inputStringForMap);
}
else
{
if(filePos == 1 || filePos == 10 || filePos == 83)
LOG.info("key contained for: " + tokenForMap);
inputStringForMap = map.get(tokenForMap);
inputStringForMap = inputStringForMap.substring(0, inputStringForMap.length()-1) + ", " + filePos + "}";
map.replace(tokenForMap, inputStringForMap);
}
我的日志是:
[exec] 19/11/22 21:54:04 INFO exercise.BasicInvertedIndex: bart Bart_the_Murderer.txt.gz filepos1
[exec] 19/11/22 21:54:04 INFO exercise.BasicInvertedIndex: no key contained for: bart
[exec] 19/11/22 21:54:04 INFO exercise.BasicInvertedIndex: bart Bart_the_Murderer.txt.gz filepos10
[exec] 19/11/22 21:54:04 INFO exercise.BasicInvertedIndex: no key contained for: bart
[exec] 19/11/22 21:54:04 INFO exercise.BasicInvertedIndex: bart Bart_the_Murderer.txt.gz filepos83
[exec] 19/11/22 21:54:04 INFO exercise.BasicInvertedIndex: key contained for: bart
如您所见,containskey()似乎并不认为filepos 10中的bart与filepos 1中的bart相同,但它认为它与filepos 83(和其他位置)中的bart相同。尽管将文档标记为以下内容,但仍然存在这种情况:
String line = value.toString().replaceAll("[^A-Za-z0-9]", " ").toLowerCase();
StringTokenizer itr = new StringTokenizer(line);
由于BART应该都是字母数字字符,没有空格(打印时看起来完全相同),我不理解containskey方法为什么不将它们关联起来。我发现有人有类似的问题,containskey无法识别文件的第一个字,尽管没有找到解决方案
感谢所有能够提供帮助的人。您可以使用以下命令而不是map.containsKey(..):
map.get(key)
如果它返回null,这意味着它不包含该键
if (map.get(key)==null){
....
}
else {
}
这也应该如此。我提出这个解决方案时假设containsKey就是您提到的问题。谢谢您的回复,尽管它并没有解决问题。问题不在于containskey方法本身,而是hashmap将这些“bart”的出现标识为不同。我认为可能有一些不可见的字符链接到文件的第一个字,但我认为replaceAll(“[^a-Za-z0-9]”,“”)可以消除这些字符。请确保标记前后没有多余的空格,请使用tokenForMap.trim()在hashmap中添加/检查其存在时。似乎不是问题。您是否尝试使用调试器查看发生了什么?我相信这将有助于发现问题。