13

I need to sort a list of Points. First I need to compare the x value, then if the x values are equal, the y value. So I thought I'd use the thenComparing method:

Comparator<Point> cmp = Comparator.comparingInt(p -> p.x).thenComparingInt(p -> p.y); 

But I keep getting the message: Incompatible types: Comparator<Object> cannot be converted to Comparator<Point>.

There are other ways I can make this comparison, and it works, but I don't understand what I'm doing wrong here.

1
  • Perhaps you need to cast it into a point by writing (Point). Not sure at all, though. Commented Mar 27, 2016 at 23:43

2 Answers 2

19

This code does work:

Comparator<Point> cmp = Comparator.<Point> comparingInt(p -> p.x) .thenComparingInt(p -> p.y); 

I only added <Point> before comparingInt, which explicitly declares the type of p in the lambda. This is necessary, since Java cannot infer the type, due to the method chain.

See also Generic type inference not working with method chaining?


Here is another alternative:

Comparator<Point> cmp = Comparator.comparingDouble(Point::getX) .thenComparingDouble(Point::getY); 

Here, the type can be inferred without any problems. However, you need to use the double comparison, because getX and getY return double values. I personally prefer this approach.

Sign up to request clarification or add additional context in comments.

2 Comments

Why not something like Collections.sort(list, (p1, p2) -> p1.x != p2.x ? p1.x - p2.x : (double) (p1.y - p2.y) ?
You are suggesting to use the following comparator: Comparator<Point> cmp = (p1, p2) -> p1.x != p2.x ? p1.x - p2.x : p1.y - p2.y; I just took some time to verify that it is doing the right thing and that indeed seems to be the case. But this is just what, in my opinion, makes your suggestion bad coding style: It is not self-explaining and it potentially duplicates code, so you have to think about it every time you write down a comparator, which easily leads to bugs that are hard to find.
5

Try changing:

Comparator<Point> cmp = Comparator.comparingInt(p -> p.x).thenComparingInt(p -> p.y); 

to

Comparator<Point> cmp = Comparator.comparingInt((Point p) -> p.x).thenComparingInt((Point p) -> p.y); 

1 Comment

Yes, I did test it and it worked fine..

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.