2

I saw an example on here how to sort an ArrayList using the Comparator interface, so I tried it out. With Strings it worked perfectly, but with one variable that I want to sort being an Integer, it will not compile, saying "int cannot be dereferenced".

What can I do so that this will work and allow me to sort an ArrayList by the score variable?

Here's my code:

public class ScoreComparator implements Comparator<Review> {
    
    @Override
    public int compare(Review o1, Review o2)
    {
       return o1.getScore().compareTo(o2.getScore());
    }
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
CSRadical
  • 113
  • 1
  • 2
  • 7
  • Please show us the code you're using to actually call the sort function. – Jashaszun Aug 05 '14 at 18:30
  • int is a primitive type, it does not implement any Object methods. – DwB Aug 05 '14 at 18:38
  • @DwB Oh hi. Are you prepared to admit you were wrong about the Monty Hall problem yet? – Boann Aug 05 '14 at 18:43
  • @Boann If by "wrong" you mean "100% correct", then yes. Otherwise, learn math you idiot. – DwB Aug 05 '14 at 19:38
  • o1.getScore() is returning int instead of Integer,possibly because of autoboxing/unboxing thing..that is the reason you are getting dereferencing error – rupesh jain Aug 05 '14 at 19:50
  • @DwB <3 you too. I'd like to learn the math but to do that I need you to go back and answer the question I put to you on July 3rd. If you're so sure you're right you have nothing to be afraid of by answering it. – Boann Aug 05 '14 at 19:55
  • Does this answer your question? [Can I use compareTo to sort integer and double values?](https://stackoverflow.com/questions/14178539/can-i-use-compareto-to-sort-integer-and-double-values) – user202729 Feb 19 '22 at 13:21

3 Answers3

9

You can't call methods on ints; there's no compareTo method to call. That would be on the boxed Integer type, but boxing would be overkill.

If you're on Java 7+, you should write

return Integer.compare(o1.getScore(), o2.getScore());

...otherwise you'll more or less need to write

if (o1.getScore() < o2.getScore()) {
   return -1;
} else if (o1.getScore() > o2.getScore()) {
   return 1;
} else {
   return 0;
}
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • 3
    Or if `getScore()` returns an `int`, you can `return o1.getScore() - o2.getScore();` – Jashaszun Aug 05 '14 at 18:26
  • 1
    This is correct, but it fails to explain why he gets the _int cannot be dereferenced_ error. I believe you should add this part to your answer as well. – Laf Aug 05 '14 at 18:29
  • 3
    @Jashaszun Careful: That works generally, but is unsafe for large values as the subtraction would overflow. – Boann Aug 05 '14 at 18:31
  • 1
    @Jashaszun This is simple and appropriate in *many* cases. But one should at least *mention* the possible over/underflow... (EDIT: Boann beat my by a few seconds ....) – Marco13 Aug 05 '14 at 18:31
  • @Boann That's a good point, but I doubt that for reviews of things the scores would be that large (or small). – Jashaszun Aug 05 '14 at 18:32
  • This actually works better than the rest. I switched the < and > in the two statements and I got the order I was looking for. Thanks! – CSRadical Aug 05 '14 at 18:35
  • Instead of `Integer.compare` you could also use `Integer.valueOf(x).compareTo(Integer.valueOf(y))` which has been there since Java 1.2. (Code plagiarized from the javadoc.) – ajb Aug 05 '14 at 19:02
  • @ajb: Yes, but that'd be wastefully boxing. – Louis Wasserman Aug 05 '14 at 19:27
1

Fyi, although this doesn't answer your specific question about the int dereferencing error, in Java 8 you don't need the dedicated comparator class at all. You can simply write:

yourList.sort((r1, r2) -> Integer.compare(r1.getScore(), r2.getScore()));

or

yourList.sort(Comparator.comparingInt(Review::getScore));

both of which are much nicer ways to do it.

Boann
  • 48,794
  • 16
  • 117
  • 146
-2

try this:

public class ScoreComparator implements Comparator<Review> {

    @Override
    public int compare(Review o1, Review o2)
    {
         return (o1.getScore()<o2.getScore() ? -1 : (o1.getScore()==o2.getScore() ? 0 : 1));
    }
}
Joel
  • 4,732
  • 9
  • 39
  • 54
rupesh jain
  • 3,410
  • 1
  • 14
  • 22
  • 1
    This solution can lead to integer underflow or overflow and consequently wrong return codes! Wasserman's solution uses the recomended approach. – ericbn Aug 05 '14 at 18:32
  • That does what I want, other than it sorts in the reverse order of what I'd like it to be at. Is there a way to change the order around? If not it's fine, I'm already ecstatic this fixes my main problem. – CSRadical Aug 05 '14 at 18:32
  • To change the order you need to invert the results, i.e. o2.getScore() - o1.getScore(). But as a previous poster said, this is dangerous as it may throw an exception. – Ralf Wagner Aug 05 '14 at 18:34