【问题标题】:Twitter fabric API: Sorting tweets based on location (nearest first)Twitter Fabric API:根据位置对推文进行排序(最近的优先)
【发布时间】:2016-08-25 06:56:39
【问题描述】:

所以我正在使用 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;
    }
}

这是在我的活动中使用该类的方式

Collections.sort(tweetsSortedByLocation, new SortLocations(currLat, currLng)); 

其中 tweetsSortedByLocation 属于 List 类型。非常感谢任何帮助:)

【问题讨论】:

    标签: android sorting twitter tweets twitter-fabric


    【解决方案1】:

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

    您当前的解决方案可能是 n + n log(n) 时间:n 用于将推文添加到集合中,然后 n log(n) 用于排序。如果您使用 PriorityQueue(在 Java 中实现为 min-heap)而不是常规 List(我假设 tweetsSortedByLocation 是),那么它会在您添加到它时进行排序,给您 n log(n) 时间:n for each每个插入的元素和 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;
    }
    

    希望能解决你的问题

    【讨论】:

    • 感谢扎克的回复!非常感谢您的综合解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多