3

I am newbie in java but I think I have done well teaching myself in these few weeks. But now I am stuck at this loop.

Here is a method from one of my class. To help me debug, I have added "myString" string and "syntax" list inside this method to demonstrate what is happening and to keep it simple, at least for now.

public void getIndex(){
    String myString = "2 2 + 3 5";
    String[] syntax = myString.split(" ");

    for (int index = 0; index < syntax.length; index++){
        System.out.println("current index is: " + index);
        System.out.println("It has: " + syntax[index]);
        // these print statements are made to help me debug
        if (syntax[index] == "+"){
            indexNeeded = index;
            break;
        }
    }
    System.out.println("Index Needed: " + indexNeeded);   

As you can see inside the loop, I want to break the "for loop" when the element of the list, "syntax" is "+". (I am showing "+" here but it can be anything in the actual program.)

Here is the output, when run this method:

current index is: 0
It has: 2
current index is: 1
It has: 2
current index is: 2
It has: +
current index is: 3
It has: 3
current index is: 4
It has: 5
Index Needed: 0

The loop should have stopped when it found "+" but it seems that "if statement" is not working at all, and hence "indexNeeded" hasn't changed.

It's a simple method but what am I doing wrong here?

jbchichoko
  • 1,574
  • 2
  • 12
  • 16
  • 2
    This is all about equality testing for strings and characters. Nothing to do with `if` or `break`. You really need to get a better tutorial, one that covers string equality checks more completely. – S.Lott Jan 04 '12 at 19:15
  • 2
    @S.Lott -- It's an easy mistake to make, even if you're fairly familiar with the topic. Highly likely for a novice, whether or not they've been exposed to the lecture on string compares. – Hot Licks Jan 04 '12 at 19:20
  • 1
    @HotLicks: Never said it wasn't easy. But the "I think I have done well teaching myself" indicates that a better tutorial is required. – S.Lott Jan 04 '12 at 19:23
  • 1
    Yeah, but it's the kind of thing you learn by doing -- after making the mistake 2-3 times you kind of "get it"(\*) -- far better than if you just listen to the lecture. (\*) (Though relapses on this point are appallingly common, even for those who've been programming for decades.) – Hot Licks Jan 04 '12 at 19:36
  • @HotLicks: "after making the mistake 2-3 times". Seems slow. A better tutorial might prevent doing this 2 or 3 times. – S.Lott Jan 04 '12 at 19:58
  • 1
    So how many times have you made the mistake?? (Be honest, now!) – Hot Licks Jan 04 '12 at 20:10
  • @HotLicks: Never. Actually. I had a good tutorial. I'm not saying head-banging is bad. Clearly, you really like it. I'm suggesting that a better tutorial might reduce the head banging for some people. If you don't want to learn more quickly, that's good. Learning slowly is just fine. – S.Lott Jan 04 '12 at 20:20
  • 1
    How long have you been programming? How many different languages? – Hot Licks Jan 04 '12 at 20:30
  • @HotLicks: Only 30 years, and only in dozens of languages. But I'm a big fan of tutorials. I apologize for implying that making mistakes isn't a good way to proceed. It is good. It seems inefficient when there are good tutorials. But if you think mistakes are better than tutorials, that's good. – S.Lott Jan 04 '12 at 20:55

8 Answers8

10

You're trying to compare strings with ==. That doesn't work, you need to use .equals():

change:

syntax[index] == "+"

to

syntax[index].equals("+")

== only returns true when both objects refer to the same instance. equals() will return true when the contents of the string are the same. This is what you want.

Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • @jbchichoko, Strings are unique and tricky in Java, because sometimes == will work fine with Strings due to the way Java handles Strings internally. You should still always use `equals`, however. – Paul Jan 04 '12 at 20:42
3

Replace

if (syntax[index] == "+"){

with

if (syntax[index].equals("+")){

When you are trying == it comparing the references and syntex[index] is not referring to same location where literal "+" is. So they are not equal.

// If syntax[index] get '+' value from somewhere but not literal
if(syntax[index] == "+" ) // is false
// right way is 
if(syntax[index].equals("+")) // is true

// If syntax[index] get '+' value from literal
syntax[index] = "+";
if(syntax[index] == "+" ) // is true
// This approach is faster but has mentioned above has limitations.

When you do equals it actually compares the content.

havexz
  • 9,550
  • 2
  • 33
  • 29
2

You should write:

syntax[index].equals("+")

"+" is a reference to a String, and syntax[index] is another. But here you want to compare the objects themselves, not their references.

If you take two objects a and b of whatever class, a == b will test that the references are the same. Testing that they are "the same" is written a.equals(b).

You should read Java's .equals() documentation carefully, it is a fundamental part to understand.

fge
  • 119,121
  • 33
  • 254
  • 329
1

for String, you need to do

syntax[index].equals("+")
Tudor
  • 61,523
  • 12
  • 102
  • 142
evanwong
  • 5,054
  • 3
  • 31
  • 44
  • == is used to test if two objects references (memory location) are the same. equals is used to test the objects equality. For objects, they can have different references even if their properties are all equals. In the case of String, even all the characters are same, they might be referring to different memory locations. – evanwong Jan 04 '12 at 21:52
  • Yes, I know - your answer said "for String" when it really applies to all Objects. – Paul Jan 04 '12 at 22:37
1

If you want to compare the value of a String you need to use .equals() but if you want to compare references you use the operator ==. That a common mistake with newbies.

Take a minute and see the difference between:

syntax[index] == "+"

and

"+".equals(syntax[index])

it that order you don't allow possible null pointer in syntax[index]

jenaiz
  • 547
  • 2
  • 15
0

Here's a fun, educational way to fix your problem. Add a call to String.intern() to your method and it will work fine. Amaze your friends! :)

public int getIndex()
{
    String myString = "2 2 + 3 5";
    String[] syntax = myString.split(" ");
    int indexNeeded = -1;
    for (int index = 0; index < syntax.length; index++)
    {
        System.out.println("current index is: " + index);
        System.out.println("It has: " + syntax[index]);
        // these print statements are made to help me debug
        if (syntax[index].intern() == "+")
        {
            indexNeeded = index;
            break;
        }
    }
    return indexNeeded;
}

Note that it is better to return a value from a method than it is to use variables with class scope. Class-scoped variables should be reserved for data that can be considered a property of the object. indexNeeded doesn't meet that description, and it's a poor name for an int - it sounds like it should be a boolean.

Paul
  • 19,704
  • 14
  • 78
  • 96
-1

Equality checks in Java come in two forms.

The equality operator "==" checks to see if two variables refer to the same object. In your case, this test fails because, though their content is the same, you're referring to two different string objects.

The .equals() method is available on every Java object and provides extensible equality checking. In the case of Strings, consider the following:

"+".equals("+") // evaluates to true

going back to the equality operator:

"+" == "+" // evaluates to false

See this page for more detail.

Mike Yockey
  • 4,565
  • 22
  • 41
  • 1
    -1 because `"+" == "+"` evaluates to true. You need to study how Java handles `String`s. – Paul Jan 04 '12 at 20:31
  • I found this answer informative: http://stackoverflow.com/a/767655/513872 Essentially, you're right, but only because of optimizations made by the JVM. The difference comes in when and where the string is constructed. Operator equality is NOT guaranteed for strings. – Mike Yockey Jan 05 '12 at 01:57
  • I should add, this optimization is in the spec, but not guaranteed outside the Oracle JVM. Users of the OpenJDK, IBM JDK, and others are likely to see different results. – Mike Yockey Jan 05 '12 at 02:01
-2

Use return; instead of break; it works for me