【问题标题】:HashMap contains a certain key but tells me it doesn'tHashMap 包含某个键,但告诉我它没有
【发布时间】:2018-11-02 13:20:52
【问题描述】:

我一直在为大学活动编写此代码:我需要从 .txt 文件中读取一些行,将它们存储在 HashMap 中并根据文件中的内容打印一些结果。 这些行是一个名字和一个数字,它们是那个人的名字和年龄。 例如:

马克 23

约翰 32

.txt 文件包含一些人名,程序运行良好,但有一个例外:读取列表的第一个名称,存储在 HashMap 中,但每次我用map.get() 或@987654322 访问它@它告诉我密钥不存在。

这个问题只发生在读取的第一个名字上。 在我给出的示例中,Mark 会发生这种情况,但如果我改变行的顺序,将 John 放在首位,它会发生在他身上,而不是 标记

请记住,键是人名,值是我为该人创建的对象 Person。

这是我的代码:

class Person {
    private String name;
    private int age;

    //Getter
    public int getAge() {
        return this.age;
    }

    public String getName() {
        return this.name;
    }

    //Constructor
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //toString
    @Override
    public String toString() {
        return name + " " + age;
    }
}
class OpenText {
    public static void textReader(String directory) {
        try {
            BufferedReader file = new BufferedReader(new FileReader(directory));
            String line;
            String[] lineSplit;

            while ((line = file.readLine()) != null) {
                lineSplit = line.split(" ");
                try {
                    int age = Integer.parseInt(lineSplit[1]);
                    Main.hMap.put(lineSplit[0], new Person(lineSplit[0], age));

                } catch (NumberFormatException exc) {
                    System.out.println(exc);
                }
            }

            file.close();
        } catch (IOException exc) {
            exc.printStackTrace();
        }
    }
}
public class Main {

    public static Map<String, Person> hMap = new HashMap<>();

    public static void main(String[] args) {
        OpenText.textReader("DIRECTORY OF THE FILE");
        System.out.println(hMap.keySet());
        System.out.println(hMap.values());
        System.out.println(hMap.get("John"));
    }

    // [John, Mark, Peter, Philip, Mary] 
    // [John 32, Mark 23, Peter 37, Philip 20, Mary 54] 
    // null
}

我想很明显我只是 Java 的新手,但任何见解都将不胜感激!

提前致谢!

【问题讨论】:

  • 请给出你写的3个print的输出
  • 尝试在你的分割方法中使用\\s+,如果有超过1个空格会有所帮助
  • 使用调试器,在最后加一个step点,在一个print处,并检查keys的内容,一个一个的,看key的内容就是一个String跨度>
  • 这里lineSplit = line.split("\\s+");
  • 你也可以在你的 iinput 上使用 trim(),像这样:Main.hMap.put(lineSplit[0].trim(), etc...

标签: java arraylist hashmap key readfile


【解决方案1】:

一些文本编辑器会在文件的开头添加不可打印的字符,这样当另一个文本编辑器读取时,它就会知道使用了哪个字符结尾。例如https://en.wikipedia.org/wiki/Byte_order_mark

BufferedReader 不对这些字符做任何特殊处理,而是将它们视为您看不到的文本。

在您的情况下,这意味着任何第一个单词实际上在开头都有一些不可打印的字符,这意味着它不是完​​全匹配。

要处理任意BOM,可以使用以下解决方案。

Byte order mark screws up file reading in Java

我会确保你一开始没有添加这些。

一个更简单的解决方案是在适合您的情况下忽略这些字符。

line = line.replaceAll("[\0\uFFFD]", "");

顺便说一句

BufferedReader br = new BufferedReader(
        new InputStreamReader(
                new ByteArrayInputStream(
                        new byte[]{(byte) 0x0, (byte) 0x0, 'H', 'i', '\n'}
                )));
String line = br.readLine();
System.out.println("line.length()=" + line.length());
System.out.println(line);

打印

line.length()=4
Hi

您需要检查 String 的实际长度是否符合您的预期。

【讨论】:

  • 是的,这绝对是问题所在。我在 .txt 文件上打印了名字和名字的长度,结果如下:prntscr.com/ldl14y 那里肯定有一个我看不到的字符,但是您提出的解决方案 (.replaceAll() ) 没有改变它。我会查看您发送的链接并报告任何进展。非常感谢,伙计!现在我知道问题所在了!
  • 这就是解决方案。原来我使用的文本编辑器正在添加这些不可打印字符之一。我所需要的只是更改文本编辑器。再次感谢您!
【解决方案2】:

我不知道您在这里使用的是什么版本的 Java。我用轻微的变化尝试了你的代码,它工作得很好。只需注意记录之间的任何新空白行。 例如-您不应该拥有像这样的文件内容:

马克 23

约翰 32

如果中间没有空行就可以了。这是我用于主类的代码

public class Main {
public static Map<String, Person> hMap = new HashMap<String, Person>();

public static void main(String[] args) {
    OpenText.textReader("C:\\Projects\\Trials\\directory\\src\\com\\hello\\nameList.txt");
    System.out.println(hMap.keySet());
    System.out.println(hMap.values());
    System.out.println(hMap.get("John"));
}

}

我刚刚将 HashMap 创建更新为new HashMap&lt;String, Person&gt;();

【讨论】:

  • 我的文件是这样的:prntscr.com/ldkx6i我更新了创建,它并没有改变任何结果....顺便说一句,我使用的是java 10
  • @MatheusPorto,我无法在工作场所访问该网址。所以如果你把它的内容粘贴到这里就好了。或以其他方式分享
猜你喜欢
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 2010-11-19
  • 1970-01-01
相关资源
最近更新 更多