четверг, 4 марта 2010 г.

Java - сравнение строк

Встала передо мной задача, сравнить пару строчек в Java.
Выглядело это примерно так:

String str1 = new String("Test");
String str2 = new String("Test");
if (str1 == str2)
System.out.println("Строчки совпадают!");

Однако, сообщение "Строчки совпадают!" не появилось.
Казалось бы, как так может быть, строки-то ведь одинаковые.
Разгадка же проста: при сравнении с помощью "==" в реальности сравниваются указатели на строки, а, так как str1 и str2 указывают на строки, находящиеся в разных местах памяти, они не равны друг другу.
Спасибо юзеру incrab, указавшему на мою ошибку в первоначальном варианте поста.
Если бы мы делали следующее:

String str1 = "Test";
String srt2 = str1;
if (str1 == str2)
System.out.println("Строчки совпадают!");

то сообщение бы вывелось, так как и str1 и str2 указывают на одну и ту же строку. (Проверить это можно, изменив str1, например str1 = "New string". Тогда, при выводе str2 на экран выведется не "Test", а "New string".

Так как же все-таки сравнить то, что находится по указателям?
У класса String существует специальный метод equals, переопределенный из класса object , возвращает true , если аргумент obj не равен null , является объектом класса string , и строка, содержащаяся в нем, полностью идентична данной строке вплоть до совпадения регистра букв. В остальных случаях возвращается значение false.

Пользоваться им можно, например, так:
if (str1.equals(str2))
System.out.println("Строчки совпадают!");

22 комментария:

Анонимный комментирует...

Проверяйте код прежде чем писать глупости.

Во первых, у вас опечатка:
String srt2 = "Test";
if (str1 == str2)

Во вторых, java в целях оптимизации для всех одинаковых строковых литералов создаёт только один объект в памяти, так что сообщение о совпадении строк вы получите и в первом случае.
Если хотите два разных объекта - создавайте их вручную:
String str1 = new String("Test");
String str2 = new String("Test");

Анонимный комментирует...

тем не менее, мне именно эта статья помогла

Анонимный комментирует...

мне тоже помогла мистика какаято ...

Ivan комментирует...

Ну если кто и заметил опечатку 5+ за внимательность"Респект, так держать, обсерай лузеров, ТЫ ЛУЧШИЙ, просто красава"
Ну,а автору статьи большое спасибо, нет просто огромное человеческое спасибо, статья помогла

Анонимный комментирует...

Зачем вводить людей в заблуждение. Условие (str1 == str2) вернёт true для конкретного случая.

Lasha87 комментирует...

mne toje pamog o4en.

Анонимный комментирует...

Прочитал статью и комментарии. Опечатка мне не сколько не помешала понять сути. Спасибо! Статья помогла.

Ivan комментирует...

В продолжение темы.
Существует задача, нужно создать цикл do-while,значений типа String.

но образовалась проблема.

String x;
String y;
do{
x=JOptionPane.showInputDialog("Значение х");
y=JOptionPane.showInputDialog("Значение y");
}while(x.equalsIgnoreCase(y));

JOptionPane.showMessageDialog(null, "Значение верно!!!");
в этом случае если значении ровны код вернётся в исходную точку. Что нужно сделать чтобы при одинаковых значениях, значение было false

Анонимный комментирует...

Спасибо, очень помогло!
Коммент про опечатку - сам глупостный)))

Анонимный комментирует...

thx автору и incrab'у %)

Анонимный комментирует...

Статья помогла, автору респект!

gennady комментирует...

String x;
String y;
do{
x=JOptionPane.showInputDialog("Значение х");
y=JOptionPane.showInputDialog("Значение y");
}while(!x.equalsIgnoreCase(y));

Если вы имели в виду: выполнять цикл, пока x и y не равны, то нужно поставить ! перед условием (! инвертирует условие, т.е. !true равно false) :))

Анонимный комментирует...

Спасибо большое.Помог.

Анонимный комментирует...

Спасибо!!!
И мне помогло.
И дело не в опечатке, что не пошло сразу.
Просто операторы сравнения применяются только к ЧИСЛОВЫМ операндам.

Анонимный комментирует...

Видимо,балбесы не читают дальше сообщения "Это опечатка", и на этом месте мозг у них сразу отключается.

Дело в том, что автор просто не пробовал проверять, что выдаёт его код, про это и писал уважаемый incrab.

Во-первых, это показывает опечатка.
Во-вторых, даже если опечатку исправить, код выдаст "Строчки совпадают!" в первом случае, в то время, как автор пишет, что это сообщение не появилось. Конечно, не появилось, если код не компилировать!

И то, что вы смогли понять суть в этот раз, не значит, что надо поощрять автора дальше писать свои статьи, не проверяя результаты.

Анонимный комментирует...

Спасибо автору.

Анонимный комментирует...

incrab, если ты вдруг прочтешь мое сообщение, подскажи где моя ошибка.

import java.util.*;
import java.io.*;

public class InputTest {

public static void main(String[] args) {

if(args.length == 0) {
System.out.println("Нужны параметры вызова: имя файла и искомое слово");
return;
}

if(args.length == 1) {
System.out.println("Не задан второй параметр вызова: искомое слово");
return;
}

String thisLine;
ArrayList list = new ArrayList();

try {

BufferedReader fin = new BufferedReader(new InputStreamReader(new FileInputStream(args[0])));
while ((thisLine = fin.readLine()) != null) {
System.out.println("==Введена строка:"+thisLine);
list.add(thisLine);
}

} catch (FileNotFoundException e) {
System.out.println("failed to open file " + args[0]);
System.out.println("Error: " + e);
return;
} catch (IOException e) {
System.out.println("I/O error on file " + args[0]);
System.out.println("Error:" + e);
return;
}

Collections.sort(list);
System.out.println("Отсортированный список строк:");
Iterator iter = list.iterator();

while( iter.hasNext() ) {
String str = (String)iter.next();
System.out.println(str);
}

int x=0;
for(int i=0; i<list.size(); i++) {
if (list.get(i) == args[1]) {
x++;
}
}
System.out.println("Найдено " + x + " совпадения с " + args[1]);
}
}

Запускаем программу с аргументами [имя файла] [слово которое нужно найти] Так вот при наличии действительных совпадений слова в файле и в аргументе, результат сравнения нулевой. Попробуйте. Вот скриншот работы программы без всяких фокусов с пробелами и т.п. Надеюсь, на разумный ответ. C уважением, Аноним. :)

http://img13.imageshost.ru/img/2012/12/12/image_50c8b2a09c74e.jpg

P.S Спасибо автору, за подсказку.

Анонимный комментирует...

Спасибо за статью! Очень помогла:)

Анонимный комментирует...

Я, конечно, дико извиняюсь, но те, кто говорит про опечатку, вообще с головой дружат?
Может автор таки поправит свою ошибку, не опечатку?
Потому что, сказав про str1 == str2, что это будет false, можно всё запороть на собеседовании.
В комменте, датированном 22 ИЮНЯ 2012 Г., 4:00, сказано все правильно. Почитайте про пул строк и про String.intern(), хотя бы.

Анонимный комментирует...

Спасибо! Помогло )

Анонимный комментирует...

Спасибо автору помогла статья очень

Анонимный комментирует...

Я может чего не понимаю, но зачем сравнивать оригинал объекта с его копией?? Это не сравнение двух разных строк (которые там типа как-то получились). Это сравнение объекта и его копии. Все равно, что a1=2; a2=a1; И зачем это сравнивать? Если с ними ни какие операции не выполнялись они и так будут одинаковыми.