Using Double in the compareTo method

Asked

Viewed 1,175 times

4

I’m having a doubt.

I have several methods of comparison, however, one of the attributes used to make the comparison is double.

Then an error occurs:

Cannot invoke compareTo(double) on the Primitive type double

I tried to convert the double to String. But he orders wrong.

He orders in order "alphabetical".

Example, sort values like this:

10, 1000, 1002, 20, 30 , 300, 40.

When it was to order like this:

10, 20 ,30 ,40 , 300, 1000 e 1002.

Here is my code:

<%! 
public static class Empreendimento implements Comparable<Empreendimento>{

// ignorar os construtores, métodos e atributos

// Para ordenar por Menor Preco
    public static void ordenaPorMenorPreco(List<Empreendimento> ArrayResultadoBusca) {
        Collections.sort(ArrayResultadoBusca, new Comparator<Empreendimento>() {
            //@Override
            public int compare(Empreendimento emp1, Empreendimento emp2) {
                return emp1.getPrecoMenor().compareTo(emp2.getPrecoMenor());
            }
        });
    }

%>

3 answers

4


The autoboxing isn’t helping.

Try to do it this way:

return Double.valueOf(emp1.getPrecoMenor()).compareTo(Double.valueOf(emp2.getPrecoMenor()));

I hope it helps.

  • It worked ! Thank you very much ! Just a doubt, what would be this autoboxing that you spoke ?

  • 1

    @Brunodm is the autoconversion of a primitive variable to a variable of an object, the inverse is called autounboxing. This serves to work with primitive objects and types in a more practical way.

  • 1

    It is the automatic conversion that the java compiler makes between primitives and their Wrappers. In short. Double d = 0; can be treated as primitive. See details on oracle website.

  • 1

    Just a hint, @Brunodm. Maybe it would be interesting to use Double in the field and not double. Then it would work as expected without the need to convert whenever you compare.

4

As you can see in the error message:

Cannot invoke compareTo(double) on the Primitive type double

You’re trying to access a method in a primitive type, but primitive types have no methods, only objects. You are working as if you are using the wrapper class object Double instead of the primitive type double.

You have three ways to solve this:

  • Change both the return of the method getPrecoMenor as to the variable it returns; or
  • Make the conversion at the time of comparison, as suggested in the other answer; or
  • Instead of using the method compareTo() could do so:

    return emp1.getD() > emp2.getD() ? 1 : emp1.getD() < emp2.getD() ? -1 : 0 ;
    

Which is basically the same solution as @Thiago, but using two ternary conditional operators. It is less readable but more compact, leaving it up to the developer who best serves it.

The third option is given because the method compareTo(), in accordance with the documentation, returns:

the value 0 if anotherDouble is numerically Equal to this Double; a value Less than 0 if this Double is numerically Less than anotherDouble; and a value Greater than 0 if this Double is numerically Greater than anotherDouble.

In free translation, the method returns:

the value 0 if the other double is numerically equal to the object that invoked the method; a value less than 0 if the value is less than the other double; and a value greater than 0 if it is greater than the other.

  • Very good this option Return emp1.getPrecoMenor() - emp2.getPrecoMenor(); ! I never thought of it that way!

  • 1

    As long as the method compareTo() actually only returns 0, 1 and -1, for practical purposes usually give the same result, unless you are using the return method in a very specific way to give some problem. But if you take into account the documentation in no time they claim that the value will be these, only says that it will be 0, positive or negative, then it is worth.

  • @Math Eu think that this solution does not always work, at least not if they are broken numbers. The problem is that Java will convert the result to int. For example, I just tested here (int) (0.1 - 0.11) and returns 0 (zero), and the expected would be -1 since 0.1 < 0.11.

  • 1

    @utluiz oh crap! Thanks for telling, I’ll do some tests here.

  • @utluiz arredondei to try to get around the situation, in a test I did worked out, but something tells me that this is not very cool, look at this: https://ideone.com/hze5sl

  • 1

    @utluiz saw no better option to do than to remove that. Not to remove my third Bullet completely I made a comparison with ternary operators, not to be the same as Thiago. Thanks!

Show 1 more comment

3

Try it this way:

     Collections.sort(lst, new Comparator<Empreendimento>() {
        @Override
        public int compare(Empreendimento o1, Empreendimento o2) {
            if(o1.getPrecoMenor() > o2.getPrecoMenor()){
                return 1;
            }else if(o1.getPrecoMenor() < o2.getPrecoMenor()){
                return -1;
            }else 
                return 0;
        }
    });
  • This seems to be the best response, in the sense that it does not involve the creation of other classes or unnecessary type conversion.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.