【问题标题】:Java I/O and HashMapJava I/O 和 HashMap
【发布时间】:2017-02-03 02:32:59
【问题描述】:

我有一个如下所示的文本文件:

A
Apple
B
Bat
C
Cat

......

我需要读取这个文本文件并将其保存在一个 HashMap 中,其中奇数行是键,下面的偶数行是值。例如,(A,苹果)。我已经尝试使用以下代码,它不起作用。有人可以给我一些提示或建议吗?

     private HashMap<String, String> newHashMap = new HashMap<String, String>();

    Charset charset = Charset.forName("US-ASCII");

    Path path = Paths.get("file_location");
    try (BufferedReader reader = Files.newBufferedReader(path, charset)) {
        int lineCount = 0;
        String key;
        String value;

        String line = reader.readLine();
        while(line != null) {


            line = reader.readLine();

            if (lineCount % 2 == 1)
            {
            key = reader.readLine() ;

            }
            else if( lines % 2 == 0)
            {
            value = reader.readLine();

            }

            lineCount++;
           newHashMap.put(key, value);
        }

【问题讨论】:

  • "...it doesn't work" -- 告诉我们很少使用。请在此处帮助我们 - 向我们提供帮助调试此问题所需的信息。
  • line = reader.readLine();放在循环的末尾。
  • 为什么不每个循环只有 2 个readLines,并避免所有的模数?
  • 只看两行,不要乱用lineCount
  • 并且不要在 if 语句中继续阅读。 line 中已有值,请使用它。

标签: java io hashmap


【解决方案1】:

正如其他人所说,if 语句和lineCount 变量在这里是多余的。第一次调用readLine 也会引起问题,因为您实际上是在跳过文本文件中的第一行。你应该做的是在你的while循环中调用(line = r.readLine()) != null),这样你就可以访问循环中的读取行,同时也能够避免在文件结束后读取。此外,while 循环 line = reader.readLine(); 内的这一行也是不必要的。它导致您每次迭代都读取额外的一行,并跳过它,因为它从未使用过。除了在 while 循环头中读取一行之外,只需在 while 循环中读取另一行并将每一行分配给正确的变量(keyvalue),如下所示,

while((line = reader.readLine()) != null) {
       key = line;
       value = reader.readLine();
       newHashMap.put(key, value);
}

在 while 循环之外,将 String line = reader.readLine(); 更改为

String line = "";

【讨论】:

    【解决方案2】:

    您已经有 keyvalue 的变量,所以请先使用 then

        String key = reader.readLine();
        String value = reader.readLine();
    
        while(key != null && value != null) {
           newHashMap.put(key, value);
           key = reader.readLine();
           value = reader.readLine();
        }
    

    【讨论】:

    • 很高兴听到。请考虑投票和/或接受我的回答
    【解决方案3】:

    您的代码的主要问题似乎是您不知道调用 bufferedReader.readLine() 方法 'n' 次会读取 'n' 行(如果它们可用)。有关详细信息,请参阅here。所以你的代码应该是这样的:-

    String key = reader.readLine();
    
    while(key!=null){
    String value = reader.readLine();
    newHashMap.put(key, value);
    key = reader.readLine();
    }
    

    如果您的输入文件没有尾随键,上述代码应该可以工作

    【讨论】:

    • 是的,我不知道。我在调试的时候就意识到了这个问题。
    【解决方案4】:

    您的方法是正确的,只需将newHashMap.put(key, value); 移动到else if 块内。在读取值之后,您只想每隔一行添加一次到地图中。

    【讨论】:

      【解决方案5】:

      调整一下就可以了

      else if( lines % 2 == 0) {
              value = reader.readLine();
              newHashMap.put(key, value); // update when you've pair of values(key + value)
      }
      

      还有一行

      String line = reader.readLine();
      

      让您跳过当前实现的第一行输入。

      【讨论】:

        【解决方案6】:

        如果您执行硬编码 +2 while 循环,您将无需 if 语句,同时能够直接关注 从每一行中提取数据。

        上面的建议只是您代码的“作弊”版本。我在下面重写了另一个版本。

        首先,您已经阅读了第一行:

        String line = reader.readLine();
        

        如果我们删除它,

        while((line = reader.readLine()) != null) {
                   newHashMap.put(line, reader.readLine());
                }
        

        我们将缩短代码。如果你看一下 while 循环,它实际上首先分配了行,所以我们只会在 put 方法中通过获取偶数元素(在本例中为键的值)来使用 readLine。

        所以简而言之,while循环携带key数据,hashmap put方法处的reader.readLine获取value数据。就这么简单,您减少了占用更多内存地址的需求。

        为了进一步加强我的回答,这里有另一个溢出。 Using BufferedReader to read Text File

        【讨论】:

          【解决方案7】:

          您无需检查lineCount 是奇数还是偶数。

          Java Docs 中 readLine() 的描述,说

          读取一行文本。一条线被任何人认为是终止的 换行符 ('\n')、回车符 ('\r') 或回车符 紧接着是换行符。

          所以,它一次读取一行。

          您可以将代码修改为:

          private HashMap<String, String> newHashMap = new HashMap<String, String>();
          
              Charset charset = Charset.forName("US-ASCII");
          
              Path path = Paths.get("file_location");
          
              try (BufferedReader reader = Files.newBufferedReader(path, charset)) {
          
                    String key = reader.readLine();
                    String value = reader.readLine();
          
                     while(key != null && value != null) {
                        newHashMap.put(key, value);
                        key = reader.readLine();
                        value = reader.readLine();
          }
          

          我在回答中借用了用户@Scary Wombat 的code。他的代码在美学上更令人愉悦,并确保您不会不小心将 null 值插入 HashMap。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-05-02
            • 2013-06-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-24
            相关资源
            最近更新 更多