Передача значения строки в массиве методу в java?

Спасибо, что нашли время, чтобы прочитать это. Извините, если мой вопрос немой, я попытался выполнить поиск, но не мог понять, почему у меня такая проблема. Я пытался проверить код для другого приложения, но у меня проблемы. Возможно, я просто неправильно понимаю массивы.

У меня есть метод с именем halfStepUp в классе с именем Transpose, который для целей тестирования должен возвращать "С#", если заданы "c" и "d #", если задано "d". Это код:

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

У меня есть следующий код в моем основном методе:

String [] scale = new String[2];
scale[0] = "c";
scale[1] = "d";

System.out.println(Transpose.halfStepUp(scale[0]));

Отпечатает "null". Что я делаю не так? Я знаю, что метод работает, потому что если я использую

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

Он отлично работает. Решение, вероятно, смущает легко, но я не мог найти хороший способ рассказать об этом при поиске помощи. Еще раз спасибо за чтение, и любые ответы очень ценятся!

Ответ 1

Попробуйте это вместо: (отредактировано из комментариев)

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;
    }   
}

Ответ 2

Чтобы добавить немного больше информации к уже полученным ответам:

Java имеет два типа хранилища. Один из них - это стек, который включает имена переменных и их значения. Одна из них - куча, это просто огромные коллекции свободно плавающих объектов.

Теперь, если вы работаете с примитивными типами (например, int, boolean или char), назначая переменную типа int myInt = 1;
толкает эту переменную на стек стека - имя myInt, значение 1.

Если у вас, однако, есть объект (например, строки), назначение переменной делает немного больше.
String myString = "Hey!";
теперь создает объект (экземпляр String) где-то в куче. В нем нет имени, а только какой-то адрес в памяти, где его можно найти.
В дополнение к этому, он подталкивает переменную в стек. Имя myString - и значение является адресом объекта в куче.

Итак, почему это имеет значение для сравнения переменных? Потому что == сравнивает значения переменных. НА СТЕКЕ, то есть. Итак, если вы сравниваете примитивные типы, все работает так, как ожидалось. Но если вы сравниваете объекты, == все еще только сравнивает значения переменных, которые в этом случае являются адресами объектов. Если адреса совпадают, он возвращает true. Это означает, что обе переменные указывают на один и тот же объект. Если адреса разные, == возвращает false., Не смотря на кучу, где объекты действительно есть.

Пример:

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

будет эхо "true" - потому что обе переменные содержат один и тот же объект.

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

будет эхо "false" - потому что теперь у вас есть два объекта в куче, а a указывает на тот, а b указывает на другой. Таким образом, хотя содержимое обоих объектов может быть одинаковым, содержимое a и b в стеке отличается.

Поэтому для сравнения любого объекта всегда используйте .equals(), если вы хотите сравнить содержимое, а не равенство экземпляров.

[Добавление]: С строками это еще сложнее. Как вы уже узнали,

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");

на самом деле даст вам "истину". Теперь почему это? Можно подумать, что мы все еще создаем два объекта. Но на самом деле мы этого не делаем.

String является неизменным. Это означает, что после создания String его нельзя изменить. Когда-либо. Не верьте? Посмотрите!

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".

Поэтому нет необходимости создавать дополнительные экземпляры String с тем же содержимым, что увеличивает производительность, поскольку строки широко используются в массах, поэтому мы хотим иметь как можно меньше из них. Чтобы архивировать это, JVM ведет список объектов String, которые мы уже создали. И каждый раз, когда мы записываем строковый литерал (что-то вроде "Hey!"), он выглядит в списках и проверяет, был ли мы уже создан экземпляр, который имеет это значение. Если это так, он возвращает указатель на тот же самый экземпляр вместо создания нового.

И ЭТО, почему "Hey!" == "Hey!" вернет true.

Ответ 3

Вы должны использовать метод .equals() при сравнении строк, а не ==. Оператор == сравнивает ссылки, чтобы увидеть, указывают ли они на один и тот же базовый объект. Метод .equals() сравнивает базовые объекты друг с другом, чтобы увидеть, являются ли они семантически эквивалентными.

Ответ 4

Сбой в этой строке:

 if (note == "c") n = "c#";

Это сравнивает строки по адресу, а не по значению. Вместо этого используйте "c".equals(note).

Ответ 5

class Transpose{
    public static String halfStepUp(String note){
        String n = null;
        if (note == "c") n = "c#";
        if (note == "d") n = "d#";
        return n;
    }
}
public class TransposeTest {
    public static void main(String... args) {
        String [] scale = new String[2];
        scale[0] = "c";
        scale[1] = "d";
        System.out.println(Transpose.halfStepUp(scale[0]));
    }
}

рабочий код