我知道我的compareTo方法有一些问题,但不知道在哪里..
这是我尝试排序的数据:
我正在查看许多.txt文件(每行大约20,000行),其中每行有一个单点数据。我正在提取一个会计年度(格式化为YYYYqX,其中X为财务季度为1-4)并将其存储为字符串。我还提取了行业代码(六位数整数)和价格指数(存储为双精度)。它存储在DataPoint对象中。
我希望输出为三列,一个是会计年度,一个是行业代码,另一个是价格指数。我想要格式化的数据,以便财政年度有序(1991q1,1991q2,...,1992q1等),行业代码的订购量至少达到最大值。因此,会计年度专栏将为每个行业代码提供许多1991q1条目,并在该季度提供价格指数。然后,当1991q1的所有行业代码用尽时,将列出1991q2的所有行业代码等。
为了实现这一点,我按如下方式构建了DataPoint compareTo方法:
public int compareTo(DataPoint p) {
int fiscalResult = compareFiscal(p.getFiscalQuarter());
if (fiscalResult > 0) {
return fiscalResult;
} else if (fiscalResult < 0) {
return fiscalResult;
} else {
if (sectorCode > 0) {
if (sectorCode > p.getSectorCode()) {
return sectorCode - p.getSectorCode();
}
else if (sectorCode < p.getSectorCode()){
return p.getSectorCode() - sectorCode;
}
else {
return 0; // Should never happen
}
}
else if (industryCode > 0) {
if (industryCode > p.getIndustryCode()) {
return industryCode - p.getIndustryCode();
}
else if (industryCode < p.getIndustryCode()) {
return p.getIndustryCode() - industryCode;
}
else {
return 0; // Should never happen
}
}
// These should never be reached
else if (p.getSectorCode() > 0) {
return -1;
}
else if (p.getIndustryCode() > 0) {
return -1;
}
else {
return 0;
}
}
}
其中compareFiscal(String)方法只是:
public int compareFiscal(String otherFiscal) {
return fiscalQuarter.compareTo(otherFiscal);
}
fiscalQuarter是包含YYYYqX会计年度的String变量的名称。
当我之前说过行业代码时,实际上会有一个扇区代码(一个四位整数)或一个行业代码(六位整数)。 DataPoint不会同时具有这两者(它没有初始化为0),因此在compareTo方法中检查sectorCode或industryCode的值。
我可以在一个文件中对这些点的列表进行排序而没有问题,但是在我的程序结束时,我从每个文件中获取所有数据点并将它们放入一个新的ArrayList(两个列表,一个用于扇区代码和一个用于行业代码。在任何时候都不能将扇区和行业代码排序在一起),并在此列表中调用Collections.sort。这是引发错误的一点。
以下是我试图调用Collections.sort方法的一点(对于行业列表,相同的一个用于扇区列表)。 DataList只是另一个表示一个文件的对象,包含两个列表,一个是所有扇区DataPoints,另一个是所有行业DataPoints。 DataLists列表只包含从每个文件创建的所有DataLists。我不认为它能说明任何事情,但只是为了相关性:
public static List<DataPoint> formatIndustryData(List<DataList> dataLists) {
List<DataPoint> data = new ArrayList<>();
for (DataList list : dataLists) {
data.addAll(list.getIndustryPoints());
}
Collections.sort(data);
return data;
}
任何人都可以在compareTo方法中看到我的逻辑出错吗?
编辑:我忘了提到,如果财政年度不同,我们会得到一个与另一个相等的行业/行业代码。 (例如,在同一财政年度,相同的行业代码从来没有两个价格指数,因为这没有多大意义。)此外,具有行业价值的DataPoints与具有扇区值的DataPoints相比毫不逊色 - 它们存储在单独的列表中,并且仅相互比较和排序。
答案 0 :(得分:1)
你的逻辑似乎不完整。
如果this
实例的sectorCode&gt; 0,你通过sectorCode进行比较,但是你没有处理p.sectorCode&lt; = 0的情况。
同样,如果this
实例的行业代码&gt; 0,您通过industryCode进行比较,但是您没有处理p.industryCode&lt; = 0的情况。
您应该决定两个属性中的哪一个 - sectorCode和industryCode - 优先。
假设对象A具有sectorCode 5和industryCode 0。 对象B具有sectorCode 0和industryCode 6。
A.compareTo(B)返回1
B.compareTo(A)也返回1
这违反了compareTo的合约,因为A&gt; B和B&gt; A不能同时为真。
如果您想先通过sectorCode进行比较,那么您的代码应如下所示:
if (sectorCode > 0) {
if (sectorCode > p.getSectorCode()) {
return 1;
}
else {
return -1;
}
} else if (p.getSectorCode() > 0) {
return -1;
} else if (industryCode > 0) {
if (industryCode > p.getIndustryCode()) {
return 1;
}
else {
return -1;
}
} else if (p.getIndustryCode() > 0) {
return -1;
} else {
return 0; // Should never happen
}
此外,如果industryCode == p.getIndustryCode()
(两者都是正数)或sectorCode == p.getSectorCode()
(两者都是正数),您应该返回0。