为什么我得到此异常java.lang.IllegalArgumentException:比较方法违反了其常规协定

时间:2019-01-11 04:22:14

标签: java android

我有这个代码。 getCreatedAt是一个很长的整数,代表记录的时间戳。

kryptoknight@Penetraitor:~/Development/Web/MyProject$ which dotnet /home/kryptoknight/dotnet/dotnet

kryptoknight@Penetraitor:~/Development/Web/MyProject$ dotnet
--info .NET Core SDK (reflecting any global.json):  Version:   3.0.100-preview-009812  Commit:    e3abf6e935

Runtime Environment:  OS Name:     kali  OS Version:  2019.1  OS Platform: Linux  RID:         linux-x64  Base Path:   /home/kryptoknight/dotnet/sdk/3.0.100-preview-009812/

Host (useful for support):   Version: 3.0.0-preview-27122-01   Commit: 00c5c8bc40

.NET Core SDKs installed:
  3.0.100-preview-009812 [/home/kryptoknight/dotnet/sdk]

.NET Core runtimes installed:   Microsoft.AspNetCore.App
3.0.0-preview-18579-0056 [/home/kryptoknight/dotnet/shared/Microsoft.AspNetCore.App]   Microsoft.NETCore.App 3.0.0-preview-27122-01 [/home/kryptoknight/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:   https://aka.ms/dotnet-download

kryptoknight@Penetraitor:~/Development/Web/MyProject$ dotnet aspnet-codegenerator identity -hIt was not possible to find any compatible framework version The specified framework 'Microsoft.NETCore.App', version '2.0.7' was not found.
  - Check application dependencies and target a framework version installed at:
      /home/kryptoknight/dotnet/
  - Installing .NET Core prerequisites might help resolve this problem:
      https://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
  - The .NET Core framework and SDK can be installed from:
      https://aka.ms/dotnet-download
  - The following versions are installed:
      3.0.0-preview-27122-01 at [/home/kryptoknight/dotnet/shared/Microsoft.NETCore.App]

当我用足够的数据运行时(列表中大约有200个项目)。我开始遇到这种异常

  

java.lang.IllegalArgumentException:比较方法违反了它的   一般合同!

当然,我在编写此代码时意识到,从理论上讲,它可能会出现整数溢出,但是感觉不太可能,因为时间戳相隔几天或几周而不是几十年。

我现在通过始终返回1,-1或0来解决此问题,但我很好奇为什么甚至首先发生此异常。

1 个答案:

答案 0 :(得分:2)

我假设时间戳为long,因为否则您将不需要(int)强制转换。

在这种情况下,这是因为溢出。 int可以保存从-2147483648到2147483647的值。如果相减结果大于或小于该值,则将结果转换为int会使结果环绕。

例如,如果record2.getCreatedAt()是2147483648,而record1.getCreatedAt()是0,那么您的函数将返回-2147483648,这表明record1更大(显然是错误的!)。

现在就可以了,这意味着您将以错误的顺序进行操作,但是它不应该崩溃,对吗?实际上,它可能会导致崩溃。

让我们调用一个具有2147483648记录A的记录,以及一个具有0记录C的记录。如果中间还有另一个记录B,时间戳为1000000000,那么您的函数会说C在A之后,A在B之后B跟在C之后。这是一个循环!无法对这些进行排序!

某些排序算法无论如何都会返回一个排序不正确的列表,但是Java使用的列表却完全混乱并抛出异常。