purpleme
purpleme

Reputation: 23

why won't my counter count properly ? it adds +1 although my if statement isnt filled

So my counter is supposed to not count +1 for the string ":DD" that's why I wrote that only if the length of my string is 2 the counter should add +1. But it adds +1 although the string length is 3. Why is that?

P.S.: I've put length() <=3 in the first if statement, for another else if that comes after the 2nd if statement.

int counter = 0;
String tgt = ":DD";

for (int i = 0; i < a.size(); i++) {
    if (tgt.length() <= 3 && tgt.charAt(0) == ':' || tgt.charAt(0) == ';') {
        if (tgt.length() == 2 &&  
            tgt.charAt(1) == ')' || tgt.charAt(1) == 'D') {
                counter += 1;
        }
    }
}

Upvotes: 2

Views: 174

Answers (3)

Turing85
Turing85

Reputation: 20185

This is a case operator precedence (source: oracle.com) not matching with the expectations we as developers might have. The &&-operator has a higher precedence than ||. This means that

tgt.length() <= 3 && tgt.charAt(0) == ':' || tgt.charAt(0) == ';'

evaluates to the same value as

(tgt.length() <= 3 && tgt.charAt(0) == ':') || tgt.charAt(0) == ';'

(Notice the parentheses around (... && ...))

If we want that the ||-operator is evaluated first, we have to add explicit parentheses:

tgt.length() <= 3 && (tgt.charAt(0) == ':' || tgt.charAt(0) == ';')

(Notice the parentheses around (... || ...))

(likewise with the 2nd if-condition)

Ideone demo

Upvotes: 3

35308
35308

Reputation: 652

The problem seems to be that your second if isn't correctly set.

If I understand correctly you want to check if the second letter is a ")" or a "D" unless the length is of two.

what your checking is if it's length = 2 and 2nd letter ")" OR that the second letter is simply equal to a "D"

you would fix it by changing the if to if ((&& tgt.charAt(1) == ')'|| tgt.charAt(1) == 'D') && tgt.length() != 2) {

Upvotes: 0

rgettman
rgettman

Reputation: 178253

The && operator has higher precedence than ||, messing up your intended logic.

The Java operators page lists Java operators in order of precedence.

Because of this, it's as if parentheses are around the two && operands:

if ((tgt.length() <= 3 && tgt.charAt(0) == ':') || tgt.charAt(0) == ';')
{
    if ((tgt.length() == 2 &&  tgt.charAt(1) == ')') || tgt.charAt(1) == 'D')

In the second if condition, the && may return false, but the second (index 1) character is 'D', so the whole condition is true and your counter gets updated.

Place explicit parentheses around your || operands, which is what I think you intended.

if (tgt.length() <= 3 && (tgt.charAt(0) == ':' || tgt.charAt(0) == ';'))
{
    if (tgt.length() == 2 && (tgt.charAt(1) == ')' || tgt.charAt(1) == 'D'))

Upvotes: 4

Related Questions