我在从多维对象阵列填充bidimensionnal双阵列时遇到了一些问题。
我的问题是空值导致java.lang.NullPointerException
at IOControl.ReadCSV$1.compare(ReadCSV.java:328)
at IOControl.ReadCSV$1.compare(ReadCSV.java:1)
at java.util.TimSort.countRunAndMakeAscending(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at IOControl.ReadCSV.run(ReadCSV.java:324)
at en.window.Main.main(Main.java:46)
,我真的不明白为什么。
我在做什么?
我正在读取一个CSV文件,我将输入逐行存储在名为Data
的对象content
数组中。
然后我填写一个名为double
的{{1}}二维数组,其中我想存储sortedOutput
和LeftSpeed
,它们是存储在NormAvgPowOutput
数组中的双值
我想要的是什么:
要让我的Data
bidimensionnal数组从维0的最小值到最大值排序:变量sortedOutput
。
那么我怎样才能避免空值?因为当我在填充第二个数组时尝试发现它们时,编译器说我无法将双精度值与LeftSpeed
值进行比较。
对不起,很长的帖子,希望你们能帮助我:) 这是我的代码:
null
编辑:所以最后我犯了2个大错误。
首先,我尝试在循环中对数组进行排序,这意味着在完全填充之前(感谢@Ted Hopp)。
其次,我没有正确处理public void run(String path, int length)
{
/*
* Main function of ReadCSV class.
* Open / reads / closes the file.
* Fills the object.
*/
BufferedReader br = null;
String input = "";
String cvsSplitBy = ",";
int[] pos = new int[200];
Data[] content = new Data[length];
Double[][] sortedOutput = new Double[length][4];
int i = 0;
int j = 0;
int k = 0;
try
{
br = new BufferedReader(new FileReader(path));
while ((input = br.readLine()) != null)
{
// use comma as separator
String[] lines = input.split(cvsSplitBy);
content[i] = new Data();
if (i == 0)
{
//not relevant here
}
else
{
j = 0;
content[i].setTime("TIME", getTime(pos[j++], lines));
content[i].setData("DATA", getContent(pos[j++], lines));
//etc
}
// gets rid of non coherent or useless values, e.g negative power, ...
if (content[i].lhWdStdev > 0 && content[i].rhWdStdev > 0)
{
normalizeData(content[i]); // not relevant
content[k].setLeftSpeed();
sortedOutput[k][0] = content[k].getLeftSpeed();
sortedOutput[k][2] = content[k].getNormAvgPowOutput();
Arrays.sort(sortedOutput, new java.util.Comparator<Double[]>()
{
public int compare(Double[]a, Double[]b)
{
return Double.compare(a[0], b[0]);
}
});
}
if (sortedOutput[k][0] == null)
{
System.out.println("FAIL");
}
System.out.println("Output = " +sortedOutput[k][0]);
i++;
k++;
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
// Again it's not relevant
}
值。我应该检查一下(null
,a != null
,b != null
,a[0] != null
)然后返回新订单。 (感谢@jboi)。
答案 0 :(得分:2)
您正在崩溃,因为您在读取所有条目之前对数组sortedOutput
进行了排序。对Arrays.sort()
的调用应该移动到您正在读取输入的循环。
或者,您可以使用扩展参数列表调用Arrays.sort()
来控制对数组的排序量:
Arrays.sort(sortedOutput, 0, k + 1, new java.util.Comparator<Double[]>()
{
public int compare(Double[]a, Double[]b)
{
return Double.compare(a[0], b[0]);
}
});
但是,我认为没有理由在每次输入后不断进行排序。
你还奇怪地在调用null
之后检查数组元素Arrays.sort()
,这要求它们不是null
。如果使用第二个选项,则至少需要在排序之前将错误检查移动。
作为第三种选择,您可以在比较器中明确允许null
数组条目。所有null
条目应该排序相同,并且应始终在非null
条目之前或之后。
答案 1 :(得分:1)
我从堆栈中看到的是,命令Double.compare(a[0], b[0]);
导致NullPointerException。这意味着,两者中的一个是null
。作为一种快速解决方案,您可以使用以下命令更改命令:
Double.compare((a[0]==null)? Double.NaN:a[0], (b[0]==null)? Double.NaN:b[0]);
这只能是快速而又脏的,因为您需要了解为什么存在空值,CSV文件中的内容,使它们为空以及如何处理此类数据。
答案 2 :(得分:0)
首先,finally子句在这里是相关的:你需要在那里调用stream br的close()方法,以避免在异常情况下发生任何资源泄漏。
其次,我认为在这里使用数组而不是列表没有优势。在java中,我们使用列表(在本例中为ArrayList)而不是数组。很少使用数组,不像C中那样.Perfs是完全相同的(提供初始化列表的大小与您对数组的大小相同)。列表更好,因为它们为您提供了更好的编译时检查,而Arrays只提供运行时检查。 例如,以下代码编译时没有错误:
String[] strings = new String[1];
Object[] objects = strings;
objects[0] = new Integer(1);
第三,当您遇到异常时,在此处发布FULL堆栈跟踪至关重要。如果有更好的信息,人们会给你更好的帮助!
幸运的是,在这里,我可以看到NPE被抛出的位置:Double.compare将两个double作为参数(而不是Double)。因此,你的Double被自动装箱加倍(google“java autoboxing”),如果它们为空则抛出NPE。您需要在比较器中处理3种无效(一种是null,另一种,以及它们两种)。或者,您可以在排序之前删除空值。