Loud Software
Loud Software

Reputation: 77

Sorting an ArrayList based on the result of a method

I have these objects in an ArrayList:

public class Foo implements Comparable<Foo> {
    ...
    private ArrayList<Double> coordinates;
    ...
}

And I have a method in my main class that outputs the distance between 2 points called :

p2pDistance(Foo x, Foo b)

What I am trying to do is sort the list according to the value given by calling p2pDistance(root,elem) root being an instance of Foo not in the original List.

My attempt was to do the following:

data.sort((o1, o2) -> (int) p2pDistance(root, o1));

(or the equivalent non-lambda expression):

data.sort(new Comparator<Foo>() {
    @Override
    public int compare(Foo o1, Foo o2) {
        return (int) Main.this.p2pDistance(root, o1);
    }
});

However, this doesn't end up working. My guess would be making a method that cycles through the List and retains the smallest result but I wanted to know why my method doesn't work and if there still is an elegant solution to this. (without having to loop through the list and find the lowest result).

Upvotes: 3

Views: 1306

Answers (2)

Kirill Simonov
Kirill Simonov

Reputation: 8481

In your code data.sort((o1, o2) -> (int) p2pDistance(root, o1)); you are not actually comparing o1 and o2. You're returning a distance as a result of compare, while comparator should return

a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

Try to use data.sort(Comparator.comparingDouble(x -> p2pDistance(x, root)));

.comparingDouble's argument is ToDoubleFunction<? super T> keyExtractor which allows you to map any object to a double value.

Upvotes: 3

EdH
EdH

Reputation: 5003

Comparable wants one of three results:

  • a negative value - o1 < o2
  • a zero value - o1 = o2
  • a positive value - o1 > o2

Presumably, your distance function is always returning a positive value. So you're likely just reverse ordering the points.

What it looks like you want is to compare the distances of both points to the root, not just o1. So, something like

return p2pDistance(root, o1) - p2pDistance(root, o2);

This will sort the WadingPool objects in the list by their distance to the root point (whatever that is).

Upvotes: 2

Related Questions