当前位置: 首页 > 知识库问答 >
问题:

排序位置:比较方法违反其总合同

顾永福
2023-03-14

我有一个类 LocationComparator,它看起来像这样:

public class LocationComparator implements Comparator<MyLocation> {

    double mLatitude, mLongitude;

    public LocationComparator(double baseLat, double baseLon){
        mLatitude = baseLat;
        mLongitude = baseLon;
    }

    @Override
    public int compare(MyLocation o, MyLocation o2) {
        float[] result1 = new float[3];
        android.location.Location.distanceBetween(mLatitude, mLongitude, o.latitude, o.longitude, result1);
        Float distance1 = result1[0];           

        float[] result2 = new float[3];
        android.location.Location.distanceBetween(mLatitude, mLongitude, o2.latitude, o2.longitude, result2);
        Float distance2 = result2[0];           

        return distance1.compareTo(distance2);
    }    
}

接下来,我有<代码>列表

Collections.sort(locations, new LocationComparator(baseLat, baseLon));

其中baseLatbaseLon是当前位置的纬度和经度。有时,代码会抛出异常 java.lang.IllegalArgumentException: 比较方法违反了其通用协定!

我知道,如果比较方法不满足传递条件,则会抛出此异常。我在这里找到了一些信息:比较方法违反了其总合同!我理解为什么在引用的问题中抛出异常,但我仍然不知道为什么在我的代码中抛出异常。

你能帮我一下吗?谢了。

更新

MyLoction的列表用于ListView的适配器。如果有新的GPS位置,则对ListView中的数据进行排序。代码如下所示:

@Override
public void onLocationChanged(Location location) {
    super.onLocationChanged(location);
    sortAdapter(new LatLng(location.getLatitude(), location.getLongitude()));
    mIsSortedByLocation = true;   
    }
}

sort适配器(latLng latLng)方法在这里:

private void sortAdapter(LatLng latLng) {
    if (mAdapter == null || latLng == null) {
        return;
    }
    List<MyLocation> list = Arrays.asList(mAdapter.getItems());
    Collections.sort(locations, new LocationComparator(latLng.latitude, latLng.longitude));
    mAdapter.setItems(mMyLocations = (MyLocation[]) list.toArray());
}

更新 2

数据来自服务器。首先,数据存储到数据库中,然后,有一个我的内容提供程序加载器。在加载完成(加载器


共有1个答案

萧懿轩
2023-03-14
匿名用户

在不了解代码细节的情况下,我会假设您的问题来自并发。

List<MyLocation> list = Arrays.asList(mAdapter.getItems());
Collections.sort(locations, new LocationComparator(latLng.latitude, latLng.longitude));

在您的示例中,它要么是打字错误,要么位置引用确实填充在方法范围之外。所以,我假设您正在从服务器加载它。或者很可能是您正在从后台线程修改Adapter的内容。

避免更改主线程使用的后台线程的数据。因此,您必须在使用集合之前对其进行同步,或者只是将结果从后台传递给主线程< code >处理程序:

List<MyLocation> locations;

void myBackgroundTask() {
    List<MyLocation> result = getLocationsFromServer();
    runOnUiThread(() -> { locations = result }); // lambda or Runnable
}

 类似资料:
  • 我已经在类上实现了Comaprable,它给了我比较方法违反了它的总合同!,由于有一些值返回为 null,代码如下 公共静态比较器名称比较器 = 新比较器() {

  • 我试图使用比较器基于两个字符串的比较对数组列表进行排序,但我最终使用的比较方法违反了它的一般契约错误。如果字符串中出现空值比较,我该如何处理? 密码 错误

  • 我目前正在Java中对集合进行排序。我收到了错误消息“比较方法违反了它的一般契约”。我也理解这个错误消息,但我(主要)使用Long类型的构建比较方法。所以我不知道,在这种情况下,排序方法仍然违反了契约。这是我的代码: 这里是错误:

  • 是的,我知道有很多问题与相同的问题,但我似乎真的找不到我的比较器有什么问题。 所以,这里是: 代码非常简单:我需要根据它们如何改变我的主要结构对一些对象进行排序,并且我首先想要最高值。 由于计算或对象的影响可能需要一些时间,我只是缓存值以便重用它们,因此在排序之前,我检查是否有缓存值或是否需要计算它。 一旦我计算出将< code>m1或< code>m2应用于我的结构的结果,我就将更改恢复。 你可

  • 我收到以下错误:“比较方法违反了它的一般合同!”当使用下面的比较器时,我无法使用jUnit复制异常。我想知道是什么导致了这个问题,以及如何复制它。有其他人也有同样的问题,但不知道如何复制。 使用以下方法调用该代码: 感谢任何帮助。 额外信息:该错误似乎发生在Java utils中的TimSort类中,并来自一个名为mergeLo的方法。链接:http://grepcode.com/file/rep

  • 我有一个类字段,和。我需要使用对它们进行排序,但我得到了一个异常: java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 我的< code>compareTo方法: 请帮我找出compareTo方法中的错误。谢了。