我目前正在处理一个程序,任何时候我称产品[1]没有空指针错误,但是,当我调用Products [0]或Products [2]时,我得到一个空指针错误。然而,我仍然得到2个不同的输出,几乎就像阵列中有[0]和1或1和2。这是我的代码
FileReader file = new FileReader(location);
BufferedReader reader = new BufferedReader(file);
int numberOfLines = readLines();
String [] data = new String[numberOfLines];
Products = new Product[numberOfLines];
calc = new Calculator();
int prod_count = 0;
for(int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if(data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
System.out.println(Products[prod_count].getName());
BigDecimal price = new BigDecimal(data[2]);
Products[prod_count].setPrice(price);
for(String dataSt : data)
{
if(dataSt.toLowerCase().contains("imported"))
{
Products[prod_count].setImported(true);
}
else{
Products[prod_count].setImported(false);
}
}
calc.calculateTax(Products[prod_count]);
calc.calculateItemTotal(Products[prod_count]);
prod_count++;
这是输出:
imported box of chocolates
1.50
11.50
imported bottle of perfume
7.12
54.62
此图片适用System.out.println(Products[1].getProductTotal());
这将成为空指针System.out.println(Products[2].getProductTotal());
这也成为空指针System.out.println(Products[0].getProductTotal());
答案 0 :(得分:3)
您正在跳过包含“输入”的行。
if(data[i].contains("input")) {
continue; // Products[i] will be null
}
可能最好将products
设为ArrayList,并仅向其中添加有意义的行。
products
也应该以小写字母开头,以遵循Java惯例。类型以大写,参数&amp;变量以小写开头。并非所有Java编码约定都是完美的 - 但这一点非常有用。
代码结构正常,但是数组不是一个非常灵活的类型来构建程序逻辑(因为长度必须预先确定,跳过需要你跟踪索引,它无法跟踪你建造它的大小。)
通常你应该构建List(ArrayList)。 Map(HashMap,LinkedHashMap,TreeMap)和Set(HashSet)也很有用。
第二个错误:波希米亚人说:在data[]
中,你混淆了所有行列表的概念,data[]
是从一行解析/拆分的令牌。
“数据”通常是无意义的术语。使用有意义的术语/名称&amp;你的程序不太可能有bug。
你应该只使用tokens
作为行标记,而不是在需要之前/之前声明它,而不是尝试按行索引 - 因为,很简单,应该完全没有必要
for(int i = 0; i < numberOfLines; i++) {
// we shouldn't need data[] for all lines, and we weren't using it as such.
String line = reader.readLine();
String[] tokens = line.split("(?<=\\d)\\s+|\\s+at\\s+");
//
if (tokens[0].equals("input")) { // unclear which you actually mean.
/* if (line.contains("input")) { */
continue;
}
当您提供问题的示例输入时,请将其编辑到问题正文中,以使其可读。将它放在评论中,无法正确阅读,只是浪费了那些试图帮助你的人的时间。
答案 1 :(得分:2)
错误提醒:您正在覆盖data
:
String [] data = new String[numberOfLines];
然后在循环中:
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
所以谁知道它有多大 - 取决于拆分的成功 - 但是你的代码依赖于numberOfLines
长。
答案 2 :(得分:0)
您需要为行号和新产品对象使用不同的索引。如果您有20行,但其中5行是“输入”,那么您只有15个新产品对象。
例如:
int prod_count = 0;
for (int i = 0; i < numberOfLines; i++)
{
data = reader.readLine().split("(?<=\\d)\\s+|\\s+at\\s+");
if (data[i].contains("input"))
{
continue;
}
Products[prod_count] = new Product();
Products[prod_count].setName(data[1]);
// etc.
prod_count++; // last thing to do
}