Java имеет одну концепцию с именем String Pool
.Каждая строка, использованная в программе, будет храниться в пуле в качестве механизма кеширования.
Например, код ниже:
String a = "StackOverFlow"; // Java will push StackOverFlow into string pool
String b = "StackOverFlow"; // Java will get address of "StackOverFlow" object in string pool and assigned to b.
В Java программистам не нужно напрямую работать с указателями.Тем не менее, указатели все еще здесь.При использовании оператора "==" примитивные переменные типа данных, такие как int, short ... будут сравниваться по своим значениям.Но в String Java будет сравниваться по их адресам.
По этой причине следующая строка вернет true:
System.out.println(a == b); // true
Однако, когда вы вызываете new String(...)
, Java создаст новый строковый объект.Он не смотрит в пул строк, чтобы проверить, сохранено ли значение строки в пуле строк или нет.По этой причине две переменные имеют одинаковое значение, они по-прежнему различаются по адресу, поэтому оператор "==" возвращает false.
String a = "StackOverFlow";
String b = new String("StackOverFlow"); // new string object. not use old one in String Pool.
System.out.println(a == b); // False. because they have different addresses.
Из-за механизма пула строк мы должны использовать метод equals
, когдасравнить два объекта.Делая это, нам не нужно заботиться о том, как строится этот объект String.Поэтому следующий код всегда возвращает true:
String a = "StackOverFlow";
String b = "StackOverFlow"; // use same object as a
String c = new String("StackOverFlow"); // create new string
System.out.println(a.equals(b)); // true
System.out.println(a.equals(b)); // true
System.out.println(a.equals(c)); // true
Что касается хеш-кода, Java будет использовать хеш-функцию для вычисления значения из символов строки.Таким образом, независимо от того, как строится строка, если две строки равны по значению, они будут иметь одинаковый хеш-код.
String a = "StackOverFlow";
String b = "StackOverFlow"; // use same object as a
String c = new String("StackOverFlow"); // create new string
System.out.println(a.hashCode() == b.HashCode()); // true
System.out.println(a.hashCode() == c.HashCode()); // true
На основании обсуждения мы можем прийти к следующему выводу.Если 2 строки имеют одинаковый хеш-код, мы не можем подтвердить, что оператор "==" возвращает true.Потому что они могут иметь одинаковое значение, но они являются разными объектами в куче памяти.
Но обратное условие является правильным.Если 2 строки указывают на один и тот же адрес, они будут иметь одно и то же значение, следовательно, один и тот же хеш-код.
Интересный вопрос : Если две строки имеют одинаковые хеш-коды, можем ли мы предположить, что эти 2 строкибудет равняться?