Java TreeMap的containsKey方法返回false,尽管键已经在映射中

Java TreeMap的containsKey方法返回false,尽管键已经在映射中,java,treemap,containskey,Java,Treemap,Containskey,我试着写一个程序来计算文本文件中的所有单词。 我在树形图中输入与模式匹配的任何单词 我通过args0获取的文本文件 例如,文本文件包含以下文本:古腾堡计划的威廉·莎士比亚全集电子书 检查树映射是否已经有单词的条件,对于单词的第二次出现返回false,但是对于单词的第二次出现返回true 我不明白为什么… 这是我的代码: public class WordCount { public static void main(String[] args) { // Char

我试着写一个程序来计算文本文件中的所有单词。 我在树形图中输入与模式匹配的任何单词

我通过
args0获取的文本文件

例如,文本文件包含以下文本:
古腾堡计划的威廉·莎士比亚全集电子书

检查树映射是否已经有单词的条件,对于单词
的第二次出现返回
false
,但是对于单词
的第二次出现返回
true

我不明白为什么…
这是我的代码:

public class WordCount
{
    public static void main(String[] args)
    {
        // Charset charset = Charset.forName("UTF-8");
        // Locale locale = new Locale("en", "US");

        Path p0 = Paths.get(args[0]);
        Path p1 = Paths.get(args[1]);
        Path p2 = Paths.get(args[2]);

        Pattern pattern1 = Pattern.compile("[a-zA-Z]");
        Matcher matcher;
        Pattern pattern2 = Pattern.compile("'.");

        Map<String, Integer> alphabetical = new TreeMap<String, Integer>();

        try (BufferedReader reader = Files.newBufferedReader(p0))
        {
            String line = null;

            while ((line = reader.readLine()) != null)
            {
                // System.out.println(line);
                for (String word : line.split("\\s"))
                {
                    boolean found = false;

                    matcher = pattern1.matcher(word);
                    while (matcher.find())
                    {
                        found = true;
                    }
                    if (found)
                    {
                        boolean check = alphabetical.containsKey(word.toLowerCase());
                        if (!alphabetical.containsKey(word.toLowerCase()))
                            alphabetical.put(word.toLowerCase(), 1);
                        else
                            alphabetical.put(word.toLowerCase(), alphabetical.get(word.toLowerCase()).intValue() + 1);
                    }
                    else
                    {
                        matcher = pattern2.matcher(word);
                        while (matcher.find())
                        {
                            found = true;
                        }
                        if (found)
                        {
                            if (!alphabetical.containsKey(word.substring(1, word.length())))
                                alphabetical.put(word.substring(1, word.length()).toLowerCase(), 1);
                            else
                                alphabetical.put(word.substring(1, word.length()).toLowerCase(), alphabetical.get(word).intValue() + 1);
                        }
                    }
                }
            }
}
公共类字数
{
公共静态void main(字符串[]args)
{
//Charset Charset=Charset.forName(“UTF-8”);
//语言环境=新语言环境(“英语”、“美国”);
Path p0=Path.get(args[0]);
Path p1=Path.get(args[1]);
Path p2=Path.get(args[2]);
Pattern pattern1=Pattern.compile(“[a-zA-Z]”);
匹配器匹配器;
Pattern pattern2=Pattern.compile(“.”);
按字母顺序映射=新树映射();
try(BufferedReader=Files.newBufferedReader(p0))
{
字符串行=null;
而((line=reader.readLine())!=null)
{
//系统输出打印项次(行);
用于(字符串字:line.split(\\s))
{
布尔值=false;
匹配器=模式1.匹配器(单词);
while(matcher.find())
{
发现=真;
}
如果(找到)
{
布尔检查=字母顺序的.containsKey(word.toLowerCase());
if(!字母顺序的.containsKey(word.toLowerCase()))
按字母顺序排列的.put(word.toLowerCase(),1);
其他的
字母顺序的.put(word.toLowerCase()、字母顺序的.get(word.toLowerCase()).intValue()+1);
}
其他的
{
匹配器=模式2.匹配器(单词);
while(matcher.find())
{
发现=真;
}
如果(找到)
{
if(!字母顺序的.containsKey(word.substring(1,word.length()))
按字母顺序排列的.put(word.substring(1,word.length()).toLowerCase(),1);
其他的
按字母顺序的.put(word.substring(1,word.length()).toLowerCase(),按字母顺序的.get(word.intValue()+1);
}
}
}
}
}

我已经测试了你的代码,没问题。我想你必须检查你的文件编码

当然是在“UTF-8”中。把它放在“不带BOM的UTF-8”中,你就没事了

编辑: 如果无法更改编码,可以手动更改。请参阅此链接:


关于

布尔检查的目的是什么
,它没有在任何地方使用!顺便说一句,我刚刚尝试了你的代码(但从文件中读取时没有使用
args
),效果很好。我知道它没有在任何地方使用,我只是在调试模式下使用这个变量。
while(matcher.find()){find=true;}
是检查单词是否与模式完全匹配。有什么帮助吗?您不需要
while循环
,我尝试了您的代码,它按预期工作!它给出了预期的输出,
布尔检查
也按预期工作!如果我使用
字符串str=“古腾堡计划威廉·莎士比亚全集电子书”
因此,
如果(!字母顺序的.containsKey(word.toLowerCase())
返回
true
作为单词的第二次出现,但是如果我使用
字符串单词:line.split(\\s))
我得到了
false
。为什么?你怎么知道它返回
true
?检查
代码不包含求反操作数!尝试写入
System.out.println(word+“:“+check)
正好在
行下方检查
并告诉我结果是什么。我的文件是
UTF-8
它是如何关联的?在读取文件时,你会在文件的开头看到一个?我想这是字节顺序标记。更改其编码为UTF-8而不带BOM,应该可以。如果我用
记事本打开文本文件,我只会看到文件是
UTF-8
,但当我用
Notepad++
打开文件时,我看到我的文件是
UTF-8-BOM
,当我将其更改为
UTF-8
时,它可以正常工作。但是我的输入文本文件不是要更改的,因为检查我程序的人不想做这些更改。我该如何改进?如果我使用:
newBufferedReader(Path,Charset)
Charset Charset=Charset.forName(“UTF-8-BOM”);
所以我得到:
线程“main”中的异常java.nio.Charset.UnsupportedCharsetException:UTF-8-BOM位于java.nio.Charset.Charset.forName(未知源代码)
我需要做什么?您可以在这里看到如何用java处理BOM(您必须手动完成) :