Passing value of a string in an array to a method in java?

11,176

Solution 1

Try this instead: (edited from comments)

public class Transpose{
    public static String halfStepUp(String note){
        String n = null;
        if ("c".equals(note)) n = "c#"; //using .equals as a string comparison
        if ("d".equals(note)) n = "d#"; //not "d"#
        return n;
    }   
}

Solution 2

To add a little more info to the answers you already got:

Java has two types of storage. One is the stack, which includes variable names and their values. One is the heap, that is just a huge collections of free-floating objects.

Now, if you're working with primitive types (like int, boolean or char), assigning a variable like
int myInt = 1;
pushes that variable on thje stack - the name is myInt, the value is 1.

If you, however, have an object (like strings are), assigning a variable does a little bit more.
String myString = "Hey!";
now creates an object (instance of String) somewhere on the heap. It has no name there, only some address in the memory where it can be found.
In addition to that, it pushes a variable on the stack. The name is myString - and the value is the address of the object on the heap.

So why is this relevant to comparing variables? Because == compares values of variables. ON THE STACK, that is. SO if you compare primitive types, everything works as expected. But if you're comparing Objects, == still only compares the values of the variables - which is, in that case, the addresses to the objects. If the addresses are the same, it returns true. That does mean, both variables point to the same object. If the addresses are different, == returns false., Without ever looking at the heap, where the objects really are.

An example:

String a = new String("Hey!");
String b = a;
if (a == b) System.out.println("true");
else System.out.println("false");

will echo "true" - because both variables contain the same object.

String a = new String("Hey!");
String b = new String("Hey!");
if (a == b) System.out.println("true");
else System.out.println("false");

will echo "false" - because you have two objects on the heap now, and a points to the one, while b points to the other. So while the contents of both objects may be the same, the contents of a and b on the stack are different.

Therefore, to compare any object, always use .equals() if you want to compare contents, not instance-equality.

[Addendum]: With strings, this is even more complicated. As you already found out already,

String a = "Hey!"; // mention the difference to the example above:
String b = "Hey!"; // I did NOT use the `String()` cosntructor here!
if (a == b) System.out.println("true");
else System.out.println("false");

will actually give you "true". Now why is THAT? One might think that we still create two objects. But actually, we are not.

String is immutable. That means, once a String has been created, it cannot be modified. Ever. Don'T believe that? Take a look!

String myString = "test"; // we create one instance of String here
myString += " and more"; // we create another instance of String (" and more")
                         // and append that. Did we modify the instance stored in
                         // myString now? NO! We created a third instance that
                         // contains "test and more".

Therefore, there is no need to create additional instances of String with the same content - which increases performance, as Strings are widely used, in masses, so we want to have as few of them as possible. To archive that, the JVM maintains a list of String Objects we already created. And every time we write down a String literal (that is something like "Hey!"), it looks in that lists and checks if we already created an instance that has that value. If so, it returns a pointer to that exact same instance instead of creating a new one.

And THIS is, why "Hey!" == "Hey!" will return true.

Solution 3

You should use the .equals() method when comparing strings, not ==. The == operator compares the references to see if they are pointing to the same underlying object. The .equals() method, compares the underlying objects to each other to see if they are semantically equivalent.

Share:
11,176
user2333867
Author by

user2333867

Updated on July 21, 2022

Comments

  • user2333867
    user2333867 almost 2 years

    thank you for taking the time to read this. Sorry if my question is dumb, I tried searching but couldn't quite figure out why I'm having this problem. I was trying to test some code for another application, but I'm having issues. Perhaps I just don't understand arrays properly.

    I have a method named halfStepUp in a class named Transpose that, for testing purposes, should return "c#" if given "c" and "d#" if given "d". This is the code:

    public class Transpose{
        public static String halfStepUp(String note){
            String n = null;
            if (note == "c") n = "c#";
            if (note == "d") n = "d"#;
            return n;
        }   
    }
    

    I have the following code in my main method:

    String [] scale = new String[2];
    scale[0] = "c";
    scale[1] = "d";
    
    System.out.println(Transpose.halfStepUp(scale[0]));
    

    This prints "null." What am I doing wrong? I know the method works because if I use

    System.out.println(Transpose.halfStepUp("c"));
    

    It works fine. The solution is probably embarrassingly easy but I couldn't find a good way to word it when searching for help. Thanks again for reading, and any answers are greatly appreciated!

  • Fabian Barney
    Fabian Barney over 10 years
    Doing it the other way around would be NPE-safe: "c".equals(note).
  • Johannes H.
    Johannes H. over 10 years
    == DOES compare strings in java - the same way it does compare ALL strings. It chekcs for instance-equality (that is: two variables point to the same object on the heap). It does, however not look into those objects, so it doesn'T recognize different objects with the same content.
  • Sterling Archer
    Sterling Archer over 10 years
    Typically you'll get downvoted for not explaining what you did to fix whatever problem
  • Mamed Khazri
    Mamed Khazri over 10 years
    my second post i dont know laws)
  • user2333867
    user2333867 over 10 years
    As soon as it lets me, I'll mark yours as best answer since yours was the first official answer. Also, Johannes, thanks for expanding on the reason why == doesn't work for these situations.
  • Sterling Archer
    Sterling Archer over 10 years
    Thanks for the tips guys, editted my answer to reflect them.
  • Johannes H.
    Johannes H. over 10 years
    @user2333867: If you want even more explanation on this, read the answer I just added.
  • Koray Tugay
    Koray Tugay over 10 years
    What is the difference between new String("Hey") and just = "Hey"
  • Johannes H.
    Johannes H. over 10 years
    @KorayTugay Using the constructor explicitely creates a new Object, while the literal uses one that has already been created with the same stirng, if such object exists.