2016-04-30 11 views
0

Fabric APIを使用してアプリを見つけ出しています。収集されたツイートをユーザーの現在地に基づいて並べ替えるオプションがあります。コンパレータを使用してソートするには、以下の方法でオンラインを見つけました。しかし、これはうまくいかないようで、前のソート結果と後のソート結果はまったく同じです。Twitterファブリック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; 
    } 
} 

これは、クラスがtweetsSortedByLocationがタイプ一覧である私の活動

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

で使用される方法です。任意のヘルプは本当に感謝しています:)

答えて

1

私は少し計算時間を失うことなくあなたの人生を少し簡単にする少し異なるアプローチをお勧めします。

現在の解決策は、n + n log(n)時間:コレクションにツイートを追加する場合はn、並べ替える場合はn log(n)です。正規リストの代わりにPriorityQueue(Javaでmin-heapとして実装されています)を使用すると、tweetsSortedByLocationと仮定すると、それを追加するとソートされ、n log(n)要素と各挿入(二分探索と考える)のlog(n)。

あなたがそう(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を返さなければならないということです。

return (int) (distanceToPlace1 - distanceToPlace2); 

distanceToPlace1とdistanceToPlace2は差が1以下でない場合は、その整数のキャストがそれをもたらします:あなたは計算する二つの距離の差が、この行の整数キャストで1未満ルックがある場合にはどうなりますこれは、比較をどのように実施しなければならないかという点で、同等性を意味します。 (https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.htmlを参照してください。)だから、(最初の最低距離距離(すなわち、ASC)をソートする)の代わりにこれを試してみてください。

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

私はそれが応答ザックため

+0

おかげで、あなたの問題を修正願っています!包括的なソリューションを本当に感謝します。 –

関連する問題