2014-10-12 96 views
0

我知道我有一些问题,我compareTo方法,但不知道在哪里..比较逻辑错误与经济数据 - 比较法违反其合同一般

这里是我想要对数据进行排序:

我正在查看许多.txt文件(每行约20000行),其中每行都有单点数据。我正在提取一个会计年度(格式为YYYYqX,其中X为会计季度的1-4)并将其存储为字符串。我还提取了一个行业代码(六位整数)和一个价格指数(存储为双倍)。这存储在一个DataPoint对象中。

我想要输出为三列,一个会计年度,一个行业代码和一个价格指数。我想要格式化的数据,以便财政年度的顺序(1991q1,1991q2,...,1992q1等),其中行业代码至少按最大值排序。因此,财政年度专栏将为每个行业代码提供许多1991Q1条目,并在该季度提供价格指数。然后,当行业1991q1所有代码已经用尽,那么所有的1991q2行业规范将陆续上市等

要做到这一点,我建我的数据点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会计年度的字符串变量的名称。

当我早些时候说过行业代码时,实际上会有扇区代码(四位整数)或行业代码(六位整数)。 DataPoint不会同时具有(它没有的初始化为0),所以这是在compareTo方法中检查sectorCode或industryCode的值。

我可以在一个文件中排序这些点的列表而不会出现问题,但是随后在我的程序结束时,我将所有数据点从每个文件中取出并放入一个新的ArrayList中(两个列表,一个用于扇区代码一个用于行业代码,并没有将行业代码和行业代码排序在一起),并在此列表上调用Collections.sort。这是抛出错误的一点。

这里有一点我正试图调用Collections.sort方法(对于行业列表,对于扇区列表使用相同的方法)。 DataList只是表示一个文件的另一个对象,其中包含两个列表,所有扇区数据点之一和所有行业数据点之一。 DataLists列表中只有每个文件创建的所有DataList。我不认为它照亮什么,但只是为相关性:

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方法出了问题?

编辑:我忘了提及,如果会计年度不同,我们会得到一个与另一个相同的部门/行业代码,这将永远不会有任何意义。 (例如,在同一财政年度,对于相同的部门代码,从来没有两个价格指数,因为这没有多大意义)。

此外,数据点在行业价值方面与具有扇区值的数据点相比 - 在任何时候都不存在 - 它们存储在单独的列表中,只能相互比较和排序。

回答

1

你的逻辑似乎不完整。

如果sectorCode this实例> 0,您可以通过sectorCode比较,但是你不处理的情况下p.sectorCode < = 0

同样,如果industryCode this实例> 0,您可以通过比较industryCode,但不处理p.industryCode < = 0的情况。

您应该决定哪两个属性 - sectorCode和industryCode - 优先。

假设对象A具有sectorCode 5和industryCode 0 对象B具有sectorCode 0和industryCode 6.

A.compareTo(B)返回1
B.compareTo(A)也返回1

这打破了compareTo的契约,因为A> B和B> 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 
    } 

此外,你应该返回0,如果industryCode == p.getIndustryCode()(当它们都正)或sectorCode == p.getSectorCode()(当它们都正) 。

+0

在同一会计年度内,行业/行业代码永远不会重复。我没有提到,我很抱歉。所以,如果财年是平等的,那么我比较行业/行业代码,而且它们永远不会相同。 – eugene1832 2014-10-12 05:51:41

+0

@ eugene1832但是如果在同一财政年度,一个对象只有sectorCode而另一个对象只有industryCode呢?这不可能吗? – Eran 2014-10-12 05:55:48

+0

啊,我看到你在问什么。因此DataPoint具有扇区代码或行业代码,并存储在两个单独的列表中,其中一个具有扇区值的DataPoints和一个具有行业值的DataPoints。这些清单永远不会合并在一起,所以它们只是在部门价值或行业价值之间进行排序,而不是两者。 例如,我在底部包含的formatIndustryData方法正在对所有包含来自所有文件的行业值的DataPoint进行排序。还有另一种方法可以为所有具有扇区值的数据点执行此操作。 – eugene1832 2014-10-12 05:57:31

相关问题