Twitter fabric API:根据位置对推文进行排序(最近的优先)

Twitter fabric API: Sorting tweets based on location (nearest first)

所以我正在使用 Fabric API 开发失物招领应用程序。它可以选择根据用户的当前位置对收集到的推文进行排序。我在网上找到了以下使用比较器进行排序的方法。然而,这似乎不起作用,排序前和排序后的结果完全一样。

public class SortLocations implements Comparator<Tweet> {
    Double currLat;
    Double currLng;

    public SortLocations(Double currLat1, Double currLng1) {
        currLat = currLat1;
        currLng = currLng1;
    }

    @Override
    public int compare(final Tweet tweet1, final Tweet tweet2) {
        double lat1 = 0, lon1 = 0, lat2 = 0, lon2 = 0, distanceToPlace1 = 0, distanceToPlace2 = 0;
        try {
            lat1 = tweet1.coordinates.getLatitude();
            lon1 = tweet1.coordinates.getLongitude();

            lat2 = tweet2.coordinates.getLatitude();
            lon2 = tweet2.coordinates.getLongitude();

            distanceToPlace1 = distance(currLat, currLng, lat1, lon1);
            distanceToPlace2 = distance(currLat, currLng, lat2, lon2);
        } catch (Exception E) {
            Log.d("No coordinates", "");
        }
        return (int) (distanceToPlace1 - distanceToPlace2);
    }

    public double distance(double fromLat, double fromLon, double toLat, double toLon) {
        double radius = 6378137;   // approximate Earth radius, *in meters*
        double deltaLat = toLat - fromLat;
        double deltaLon = toLon - fromLon;
        double angle = 2 * Math.asin(Math.sqrt(
                Math.pow(Math.sin(deltaLat / 2), 2) +
                        Math.cos(fromLat) * Math.cos(toLat) *
                                Math.pow(Math.sin(deltaLon / 2), 2)));
        return radius * angle;
    }
}

这就是 class 在我的 activity

中的使用方式
Collections.sort(tweetsSortedByLocation, new SortLocations(currLat, currLng)); 

其中 tweetsSortedByLocation 是列表类型。非常感谢任何帮助:)

我可能会建议一种稍微不同的方法,它可以让您的生活更轻松一些,而且不会浪费任何计算时间。

您当前的解决方案可能是 n + n log(n) 次:n 次用于将推文添加到集合,然后 n log(n) 次用于排序。如果您使用 PriorityQueue(在 Java 中作为最小堆实现)而不是常规列表(我假设 tweetsSortedByLocation 是),那么它会在您添加时进行排序,给您 n log(n) 时间: n 用于每个元素,log(n) 用于每次插入(想想二进制搜索)。

您可以像这样使用 PriorityQueue (https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html):

PriorityQueue<Tweet> tweetsSortedByLocation = new PriorityQueue<>(10, new SortLocations(currLat, currLong));
tweetsSortedByLocation.add(new Tweet());    // Or however you add them now

您也可以内联比较器,但使用 SortLocations 更好。

现在关于为什么排序时没有任何变化,这意味着 compare() 必须每次都返回 0。如果您计算的两个距离之间的差异小于 1,就会发生这种情况。查看此行上的整数:

return (int) (distanceToPlace1 - distanceToPlace2);

如果 distanceToPlace1 和 distanceToPlace2 的差异不超过 1,则整数转换将其变为 0,这在必须实现比较的方式中意味着相等。 (参见 https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html。)所以,试试这个(首先对最小距离进行排序(即按距离升序)):

if (distanceToPlace1 < distanceToPlace2) {
    return -1;
} else if (distanceToPlace1 > distanceToPlace2) {
    return 1;
} else {
    return 0;
}

希望能解决您的问题