java - 为什么我会出现差一错误?

标签 java

在下面的代码中,我只是想计算某个项目在文件中出现的次数。但是,当我打印出键及其值时,我得到的计数比实际值多了一个。当我将 total 初始化为 0 时,它解决了问题,但我不确定为什么。

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;

public class Problem {
   public static void main(String[] arg) {
      HashSet QID = new HashSet();
      HashMap QIDToCorrect = new HashMap();
      try {
         // Open the file that is the first command line parameter
         FileInputStream fstream = new FileInputStream(
               "C:/Users/lol/Downloads/data.csv");

         // Get the object of DataInputStream
         DataInputStream in = new DataInputStream(fstream);
         BufferedReader br = new BufferedReader(new InputStreamReader(in));

         //Read File Line By Line
         String strLine;
         br.readLine(); //skip header line
         int total = 0;
         int blah = 0;
         while ((strLine = br.readLine()) != null) {

            String[] split = strLine.split(",");

            if (!QID.contains(split[0])) {
               total = 1;
               QID.add(split[0]);
               QIDToCorrect.put(split[0], total);
            } else {
               total += 1;
               QIDToCorrect.put(split[0], total);
            }

            //System.out.println();
         }
      } catch (Exception e) {
      }
   }
}

最佳答案

假设您输入的每行的第一个元素如下:

foo
foo
bar
foo

现在让我们考虑一下循环如何处理此输入

while ((strLine = br.readLine()) != null) {

        String[] split = strLine.split(",");

split[0] 是第一个“foo”。

        if (!QID.contains(split[0])) {

“foo”尚未添加

           total = 1;
           QID.add(split[0]);
           QIDToCorrect.put(split[0], total);

total 设置为 1,将“foo”添加到 QID 并将 (“foo”, 1) 添加到 QIDToCorrect

        String[] split = strLine.split(",");

split[0] 是第二个“foo”

        if (!QID.contains(split[0])) {

计算结果为 false,因此 if 语句落入 else

        } else {
           total += 1;
           QIDToCorrect.put(split[0], total);
        }

total 增加到 2,QIDToCorrect 更新为 ("foo", 2)。

        String[] split = strLine.split(",");

split[0] 现在包含“bar”。

        if (!QID.contains(split[0])) {
           total = 1;
           QID.add(split[0]);
           QIDToCorrect.put(split[0], total);

QID 不包含 bar,因此 total 重置为 1,“bar”被添加到 QID,并且 (“bar” , 1) 被插入到 QIDToCorrect 中。

        String[] split = strLine.split(",");

现在 split[0] 包含第三个​​“foo”

        if (!QID.contains(split[0])) {

“foo”之前已经见过,所以转到else

        } else {
           total += 1;
           QIDToCorrect.put(split[0], total);
        }

total 增加到 2,QIDToCorrect 更新为 ("foo", 2)。

因此,保存计数器的 map 认为只有两个 foo。我在这里看到一个问题。每次您看到新项目时,您的总计计数器都会重置。因此,当您调用 QIDToCorrect.put() 时,您不会考虑过去看到该项目的次数。您可能需要使用 QIDToCorrect.get() 才能获取项目的先前计数。这消除了对 total 变量的需要(除非您想知道您所看到的所有项目的总数)。此外,QID HashSet 是不必要的,因为如果它已包含 key ,您可以查询 QIDToCorrect

关于java - 为什么我会出现差一错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14409005/

相关文章:

java - 使用 Tycho 项目构建 eclipse 功能时偶尔会出错

java - 我有一个带有 1 个 setter 方法的抽象类 - 参数是一个对象。我想要一个通用的 <T> 参数,它采用扩展它的类的类型

java - 在 Java 中使用 Gson 从嵌套对象读取单个值

java - 在 Spring Boot RequestMapping 中添加方法

java - 在模拟器上按下某个键之前,ListView 不会更新

java - 如何打印整数00而不是java打印0

java - 有用于 Tomcat 的 jBPM 7.5.0 版本吗?

java - 用 box2d 检测物体碰撞的干净方法

java - NoClassDefFoundError : org/bouncycaSTLe/jce/spec/ECPublicKeySpec even though bouncycaSTLe is available

java - 将 Tuple2 添加到 Scala 列表