0

I'm developing an Android app. I need to sort an array based off of the sorting of another. I'm sorting one (distance) based off of lowest to highest, and need for my longitude values to be sorted according to the distance. So say if distance 5 had longitude 41.2265 and distance 6 had longitude 41.2187, I would need to sort the distances from lowest to highest, {5,6}, and then sort the longitudes based off of their first pair. I have read that you could do this with a 2D array, but I would prefer not to do this. I think this also could be done with mapping, but I'm not sure how. My code is below:

Part of NearestStations.java

            ArrayList<String> distancetos = new ArrayList<String>();
            ArrayList<String> longitudeArray = new ArrayList<String>();

            while(iterator.hasNext()){
            for (int i=0; i<144;i++){

            double distance = 0;  

            double lat_end = 0;
            double lon_end = 0;


            try {
                lat_end = Double.parseDouble(iterator.next());
                lon_end = Double.parseDouble(iterator1.next());
                longitudeArray.add(Double.toString(lon_end));
                Log.i("Lon_end", String.valueOf(lon_end));

            } catch (NumberFormatException e) {
                Log.v("Main", "Convert to Double Failed : ");
            }

            Location locationA = new Location("point A");  
            locationA.setLatitude(latitude);  
            locationA.setLongitude(longitude);  

            Location locationB = new Location("point B");  
            locationB.setLatitude(lat_end);  
            locationB.setLongitude(lon_end);  

            distance = locationA.distanceTo(locationB) * 0.000621371192237334;
            Log.i("distancebefore", String.valueOf(distance));

            String dista = Double.toString(distance);


            distancetos.add(dista);
            }
            }


                Collections.sort(distancetos);

                distancea = distancetos.get(0);
                distance1 = distancetos.get(1);

                String Longa = longitudeArray.get(0);
                String Long1 = longitudeArray.get(1);


                Log.i("distanceafter", String.valueOf(distancea));
                Log.i("distance1after", String.valueOf(distance1));


            String[] Stations = getResources().getStringArray(R.array.Stations);
            String[] Longitude = getResources().getStringArray(R.array.Longitude);
            String[] Latitude = getResources().getStringArray(R.array.Latitude);



            Map<String, String> myMap = new HashMap<String, String>();{
            for (int i = 0; i <144; i++) {
                myMap.put(Latitude[i], Stations[i]);
            }
            }

            Map<String, String> myMap1 = new HashMap<String, String>();{
            for (int h = 0; h <144; h++) {
                myMap1.put(Longitude[h], Stations[h]);

            }
            }

            String value = myMap1.get(Longa);
   }
}

Thank you for your help.

3
  • I really can't tell from your code what you're trying to do, but I'm pretty sure that sorting an array of Strings (distancetos) is not what you want. This compares things in "alphabetical" (lexicographic) order and will make "100.12345" appear less than "45.00032" since the character '1' comes before '4'. Commented Oct 15, 2013 at 1:29
  • @ajb That's something I never thought of. I'm going to be finding distances of <10 miles however, so I don't think that it'll affect it. Correct me if I'm wrong. Commented Oct 15, 2013 at 1:32
  • It's bad practice in general. If you want to compare numbers, then compare numbers; don't compare strings. You never know when some unexpected data will come back to bite you. Commented Oct 15, 2013 at 1:36

2 Answers 2

2

I believe this is what you're looking for.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

public class GenericCachedSorter {
    public static void main(String[] args) {
        List<Double> distances = new ArrayList<>(Arrays.asList(1d, 2d, 3d));

        sort(distances, new ToComparable<Double, Double>() {
            @Override
            public Double toComparable(Double distance) {
                // return the longitude associated with this distance
                return getLongitude(distance);
            }
        });

        for (Double distance : distances)
            System.out.println(distances);
    }

    public interface ToComparable<T, C extends Comparable<? super C>> {
         C toComparable(T t);
    }

    public static <T, C extends Comparable<? super C>> void sort(List<T> list, ToComparable<T, C> function) {
       class Pair implements Comparable<Pair> {
          final T original;
          final C comparable;

          Pair(T original, C comparable) {
             this.original = original;
             this.comparable = comparable;
          }

          @Override
          public int compareTo(Pair other) {
                return
                  comparable == null && other.comparable == null ? 0 :
                  comparable == null ? -1 :
                  other.comparable == null ? 1 :
                  comparable.compareTo(other.comparable);
          }
       }

       List<Pair> pairs = new ArrayList<>(list.size());
       for (T original : list)
          pairs.add(new Pair(original, function.toComparable(original)));

       Collections.sort(pairs);

       ListIterator<T> iter = list.listIterator();
       for (Pair pair : pairs) {
          iter.next();
          iter.set(pair.original);
       }
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

It says for the line return getLongitude(distancetos);, The method getLongitude(ArrayList<Double>) is undefined for the type new Neareststations.ToComparable<Double,Double>(){}. What's the problem?
All you need to do in that line is return the longitude associated with that particular distance. The method getLongitude(Double distance) doesn't take an ArrayList argument.
Ah, that make sense. What do you think would be the easiest way to do it? It looks like they have not been sorted yet, so I could to longitude.get(0) and that would get index 0. Would I need an iterator for this, too?
Hey, how can I execute the sorting (these lines of code)? How do I start it from my main thread? @pscuderi
Would this work? new GenericCachedSorter().main(Latitude);?
1

How about making a class for them?

public class Coord{
    private int id;
    private double lat;
    private double long;

    public double getDistanceFrom(Coord coord);

}

That should help you because it decouples locations from administrative tasks - if you were writing C your approach would be a good one. But you're writing Java.

Moreover: The for loop will silently fail because you deplete the iterator without checking for a hasNext(). That's only done at the outer loop. So

int i=0;
while(iterator.hasNext() && iterator1.hasNext()){ //also check iterator1
     if(i>=144) break; //that's what your for loop essentially did
        double distance = 0;  
        double lat_end = 0;
        double lon_end = 0;

        try {
            lat_end = Double.parseDouble(iterator.next());
            lon_end = Double.parseDouble(iterator1.next());
            CoordArray.add(new Coord(lat_end, lat_long));
            Log.i("Lon_end", String.valueOf(lon_end));

        } catch (NumberFormatException e) { ... }
//more stuff here
i++;
}/*while loop*/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.