2016-04-30 9 views
0

Also ich entwickle eine verlorene und gefundene App mit Fabric API. Es besteht die Möglichkeit, die gesammelten Tweets basierend auf dem aktuellen Standort des Benutzers zu sortieren. Ich habe den unteren Weg online gefunden, um mit einem Komparator zu sortieren. Dies scheint jedoch nicht zu funktionieren und die Vorsortier- und Nachsortierergebnisse sind völlig gleich.Twitter Fabric API: Sortierung Tweets basierend auf Standort (am nächsten)

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; 
    } 
} 

Dies ist, wie die Klasse in meiner Tätigkeit verwendet wird

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

Wo tweetsSortedByLocation vom Typ Liste ist. Jede Hilfe wird wirklich geschätzt :)

Antwort

1

Ich könnte vorschlagen, ein etwas anderer Ansatz, der Ihr Leben ein wenig einfacher wird, ohne Rechenzeit zu verlieren.

Ihre aktuelle Lösung ist wahrscheinlich n + n log (n) Zeit: n zum Hinzufügen von Tweets zur Sammlung und dann n log (n) zum Sortieren. Wenn Sie eine PriorityQueue (implementiert als Min-Heap in Java) anstelle einer regulären Liste verwenden (wie ich annimmt, dass tweetsSortedByLocation ist), sortiert sie sich so, wie Sie sie hinzufügen, und gibt Ihnen n log (n) time: n für jeden Element und log (n) für jede Einfügung (denke binäre Suche).

können Sie eine Priorityqueue wie so verwenden (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 

Sie könnten auch den Vergleicher-line, aber SortLocations Verwendung ist besser.

Nun, warum sich nichts ändert, wenn Sie sortieren, bedeutet dies, dass compare() immer 0 zurückgeben muss. Das würde passieren, wenn der Unterschied zwischen den beiden Distanzen Sie berechnen, ist kleiner als 1. Betrachten Sie die ganze Zahl Besetzung auf dieser Linie:

return (int) (distanceToPlace1 - distanceToPlace2); 

Wenn distanceToPlace1 und distanceToPlace2 sind nicht mehr als 1 Unterschied, dass Integer-Besetzung bringt es zu 0, was, wie vergleichen muss, Gleichheit bedeutet. (Siehe https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html.) Also, versuchen Sie dies statt (am wenigsten Abstand zu sortieren zuerst (d aufsteigend nach Entfernung)):

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

Ich hoffe, dass behebt Ihr Problem

+0

Vielen Dank für die Antwort Zach !. Schätzen Sie Ihre umfassende Lösung. –

Verwandte Themen