The Time
The Time

Reputation: 737

Sort two dimensional ArrayList

I am trying to get the shorest distance and its stop_lat, stop_lon between the incoming latD, longD and the stored one in the stops table. I am storing the lat_stop, lon_stop, distStops in double tow dimensional arrayList. Currently I am getting this error

Example:

(140.4, 83.346723, 12.567835),

(90.6, 83.0984543, 10.347291),

(6.4, 83.6453974, 12.570937),

(25.7, 83.198472, 13.7364563)

I want to get this set (6.4, 83.6453974, 12.570937)

How can I get the shortest distance and its related stop_lat, stop_lon?

I appreciate any help.

            // the stops and arrrivaltimes tables exist.

            PreparedStatement preparedLatLong = con
                    .prepareStatement("SELECT lat, longi, name from stops");
            ResultSet rsLatLong = preparedLatLong.executeQuery();

            // ArrayList<Double> distanceHistory = new ArrayList<Double>();
            ArrayList<List<Double>> distanceHistory = new ArrayList<List<Double>>();

            while (rsLatLong.next()) {
                double lat_stop = rsLatLong.getDouble("lat");
                double lon_stop = rsLatLong.getDouble("longi");
                double distStops = haversineDistance(latD, longD, lat_stop,
                        lon_stop);
                distanceHistory.add(Arrays.asList(distStops, lat_stop,
                        lon_stop));
                ;


            }
            //Find the shortest diestance and its related longi and lati
            Collections.sort(distanceHistory,
                    new Comparator<ArrayList<Double>>() {

                        @Override
                        public int compare(ArrayList<Double> o1,
                                ArrayList<Double> o2) {
                            // TODO Auto-generated method stub
                            return o1.get(0).compareTo(o2.get(0));
                        }

                    }

            );

Upvotes: 0

Views: 1456

Answers (2)

RealSkeptic
RealSkeptic

Reputation: 34618

You have defined your distanceHistory list as ArrayList<List<Double>>. This means that each element in this list is a List<Double>.

But then, you defined your comparator as a Comparator<ArrayList<Double>>. This means that it expects the items it compares to be specifically ArrayList<Double>.

When you use Collections.sort, it expects a comparator whose base type is more general than the base type of the collection. And ArrayList<Double> is not more general than List<Double>.

The simple solution is to change the definition of the comparator to Comparator<List<Double>>.

But this design is really not very good. You are supposed to use lists for "similar" things. A list of three doubles that do not represent the same sort of information is not a good design. It would be better to create a small class for this:

private static class StopItem implements Comparable<StopItem> {
    double stopLat, stopLon, stopDist;

    public StopItem( double stopLat, stopLon, stopDist ) {
        this.stopLat = stopLat;
        this.stopLon = stopLon;
        this.stopDist = stopDist;
    }

    // Getters, setters...

    @Override
    public int compareTo( StopItem otherItem ) {
        return Double.compare( this.stopDist, otherItem.stopDist );
    }

}

You can then create a list of these objects, and use Collections.sort() on it, and you don't need an extra comparator.

For example, here is how you'd fill your list:

    List<StopItem> distanceHistory = new ArrayList<>();

    while (rsLatLong.next()) {
        double latStop = rsLatLong.getDouble("lat");
        double lonStop = rsLatLong.getDouble("longi");
        double distStop = haversineDistance(latD, longD, latStop, lonStop);
        StopItem newItem = new StopItem( latStop, lonStop, distStop );
        distanceHistory.add(newItem);

    }

And then you can use Collections.sort(distanceHistory).

Upvotes: 3

Anders R. Bystrup
Anders R. Bystrup

Reputation: 16050

First of all, the Comparator should take two arguments of type List<Double>:

Collections.sort( distanceHistory,
                  new Comparator<List<Double>>()
                  {
                       @Override
                       public int compare(List<Double> o1,List<Double> o2 ) {
...

since that's type of the elements of

ArrayList<List<Double>> distanceHistory = new ArrayList<List<Double>>();

(Does your code even compile as it is?)

Secondly you might want to work on your data structure a bit; perhaps a tuple/class with three attributes rather than just a List - right now you're in object denial :-) Eg.

class MyThingy implements Comparable<MyThingy> {
    Double lat, lon, dist;

    @Override compareTo( MyThingy other ) {
        // implement sensibly.
    }
}

Then you can just

List<MyThingy> distanceHistory = new ArrayList<MyThingy>();    
...
Collections.sort( distanceHistory );

without having to supply an anonymous comparator.

Cheers,

Upvotes: 0

Related Questions