1

Android アプリケーションには、場所のリストがあります。ユーザーの場所との距離に基づいて並べ替える必要があります。そのために、カスタム コンパレータを実装しました。

Collections.sort(houseList, new Comparator<HouseEntity>()
  {
     @Override
     public int compare(HouseEntity house1, HouseEntity house2)
     {
        if(userLocation == null) return 0;
        return (int) (userLocation.distanceTo(house1.location) - userLocation.distanceTo(house2.location));
     }
  });

私が行ったすべてのテストでうまく機能しています。ただし、一部のユーザーは次のエラーでクラッシュしました。

java.lang.IllegalArgumentException: Comparison method violates its general contract!

SO に関する他のすべての同じ問題を読んだ後、ロジックにエラーがある可能性がある場合にこのエラーが表示されると結論付けました (たとえば、a>b と b>a が同時に発生する可能性があります)。しかし、その論理エラーを再現するシナリオは見つかりませんでした。

このエラーの原因として考えられるシナリオは何ですか? どうすれば解決できますか?

助けてくれてありがとう

4

2 に答える 2

1

Peter Lawreyが言ったように、int にキャストする代わりに or を使用する必要がありますDouble.compare(x, y)Float.compare(x, y)ここに説明があります:

Comparator は推移的でなければなりません。つまり、A == B および B == C の場合は常に A == C です。3 つの pointsABありC、ユーザーの位置までの距離が 0.2、0.4、および 1.3 であるとします。

  1. (整数) (0.2 - 0.4) = (整数) (-0.2) = 0 =>A == B
  2. (整数) (0.4 - 1.3) = (整数) (-0.9) = 0 =>B == C
  3. (整数) (0.2 - 1.3) = (整数) (-1.1) = -1 =>A < C

ご覧のとおり、コンパレーターは推移的ではありません。

于 2013-01-18T12:46:19.440 に答える
0

もしそうuserLocation == nullならhouse1.equals(house2)、真を与えるべきです。

于 2013-01-18T11:44:32.297 に答える