Can I use CompareTo in a boolean function?

91 views Asked by At

I want to sort city names alphabetically, so I'm using CompareTo to compare city names to sort them. But the CompareTo is giving me an Int and the && isn't liking that. Also, a note - I am not allowed to use arrays.

sFirst = (sCity1.compareToIgnoreCase(sCity2) != 0) && (sCity1.compareToIgnoreCase(sCity3)) ?
                sCity1 : sCity2.compareToIgnoreCase(sCity3) ? sCity2 : sCity3;

I've tried putting a > 0 before the && but that didn't seem to do anything and I'm out of ideas.

3

There are 3 answers

1
Reilas On

"Can I use CompareTo in a boolean function? ..."

No, the returning value must be a boolean.

The String#compareToIgnoreCase method is going to return the difference.

Here is a way to evaluate the returning value.

  • "a".compareToIgnoreCase("b") will be negative
  • "a".compareToIgnoreCase("a") will be zero
  • and, "b".compareToIgnoreCase("a") will be positive

To correct your conditional-statement, you'll need to add these.

sFirst
    = sCity1.compareToIgnoreCase(sCity2) < 0
        ? sCity1.compareToIgnoreCase(sCity3) < 0
            ? sCity1
            : sCity3
        : sCity2.compareToIgnoreCase(sCity3) < 0
            ? sCity2
            : sCity3;

Or, use a stream.

sFirst = Stream.of(sCity1, sCity2, sCity3).sorted().toList().get(0);
3
kxrtik On

Summary

The stack trace should tell you exactly what to do:

/tmp/oCi20I0eY4/HelloWorld.java:9: error: bad operand types for binary operator '&&'
        String sFirst = (sCity1.compareToIgnoreCase(sCity2) != 0) && (sCity1.compareToIgnoreCase(sCity3)) ?
                                                                  ^
first type:  boolean
  second type: int

/tmp/oCi20I0eY4/HelloWorld.java:10: error: incompatible types: int cannot be converted to boolean
                sCity1 : sCity2.compareToIgnoreCase(sCity3) ? sCity2 : sCity3;
                                                   ^
2 errors

You need to convert the int returned by compareToIgnoreCase in all cases. You can transform the int to boolean using any of <, <=, >, >=, ==, !=. See compareToIgnoreCase to understand the int returned by compareToIgnoreCase and this should give you an idea of what operator to use for your question.

Long answer

You're on the right track, but I suggest you take another look at compareToIgnoreCase documentation, specifically the return values as suggested by Hovercraft Full of Eels.

To solve the actual error, see Scary Wombat's comment. To reiterate: In one case, you convert the int returned by compareToIgnoreCase to boolean but not for the others.

I would suggest that you avoid casual language like "<operator> doesn't like <condition>" and stick to more formal language like "<operator> cannot operate on integers".

In my opinion, formal language forces you to be more descriptive, which requires you to pay more attention to things like documentation or error logs. If you had to explain why "&& isn't liking the integer" then you will be answering your own question. As a bonus, it also helps whoever answers your question to know what exactly your issue is. You will have a more concrete question such as: "How do I transform Y so it matches the expectations of operator X?".

Also, please look at the error log closely since it pretty much explains how to fix the error in this case. Not sure what you see but this is what I see when running a version of your code:

/tmp/oCi20I0eY4/HelloWorld.java:9: error: bad operand types for binary operator '&&'
        String sFirst = (sCity1.compareToIgnoreCase(sCity2) != 0) && (sCity1.compareToIgnoreCase(sCity3)) ?
                                                                  ^
first type:  boolean
  second type: int
/tmp/oCi20I0eY4/HelloWorld.java:10: error: incompatible types: int cannot be converted to boolean
                sCity1 : sCity2.compareToIgnoreCase(sCity3) ? sCity2 : sCity3;
                                                   ^
2 errors

Both these errors have enough descriptions to identify a solution. Start from here, and even reference this in your question.

0
Madhu Patel On

The issue you're having with the && operator is because you're comparing the result of sCity1.compareToIgnoreCase(sCity2) (which is an integer) with the result of sCity1.compareToIgnoreCase(sCity3) without properly forming your conditional statement.

Here's a corrected way to do it:

(sCity1.compareToIgnoreCase(sCity2) < 0 && sCity1.compareToIgnoreCase(sCity3) < 0) ? sCity1 :
            (sCity2.compareToIgnoreCase(sCity1) < 0 && sCity2.compareToIgnoreCase(sCity3) < 0) ? sCity2 : sCity3;