Nano Hash - криптовалюты, майнинг, программирование

Демонстрация сравнения строк с Java

Я хочу продемонстрировать с помощью нескольких строк кода, что в Java для сравнения двух строк (String) вы должны использовать equals() вместо оператора ==.

Вот что я пробовал:

public static void main(String Args[]) {
   String s1 = "Hello";
   String s2 = "Hello";

   if (s1 == s2)
      System.out.println("same strings");
   else
      System.out.println("different strings");
}

Я ожидал этого вывода: different strings, потому что с тестом s1 == s2 я фактически сравниваю две ссылки (т.е. адреса) вместо содержимого объекта.

Но на самом деле я получил такой результат: same strings!

Просматривая Интернет, я обнаружил, что некоторые реализации Java оптимизируют приведенный выше код так, что s1и s2 будут фактически ссылаться на одну и ту же строку.

Хорошо, как я могу продемонстрировать проблему, используя оператор == при сравнении строк (или объектов) в Java?


  • На самом деле, согласно JLS, все компиляторы Java должны выполнять эту оптимизацию. 31.08.2010

Ответы:


1

Компилятор делает некоторые оптимизации в вашем случае, так что s1 и s2 действительно являются одним и тем же объектом. Вы можете обойти это, используя

String s1 = new String( "Hello" );
String s2 = new String( "Hello" );

Тогда у вас есть два разных объекта с одинаковым текстовым содержимым.

31.08.2010
  • Благодарность ! Я не знал, что использование new или нет при создании экземпляра String приведет к чему-то другому! 01.09.2010

  • 2

    Хорошо, как я могу продемонстрировать проблему, используя оператор == при сравнении строк (или объектов) в Java?

    Вот способ:

    String s = "ab";
    String t = new String("ab");
    System.out.println(s == t); // false
    

    Также будьте осторожны при сравнении примитивных оболочек и использовании автоупаковки: Integer (и Long), например, кэширует (и повторно использует!) значения -128..127. Так:

    Integer s = -128;
    Integer t = -128;
    System.out.println(s == t);
    

    напечатает true, а:

    Integer s = -129;
    Integer t = -129;
    System.out.println(s == t);
    

    печатает false!

    31.08.2010
  • Спасибо. Я не знал о кэшировании значений -128..127. Я не уверен, что понимаю, почему Java делает это, но полезно знать! 01.09.2010
  • @ Жером, это сделано потому, что разработчики думали (думали), что эти значения использовались так часто, что было выгодно не создавать новые экземпляры этих значений каждый раз. А поскольку они неизменяемы, не помешает повторное использование этих экземпляров. 01.09.2010
  • Это отличный пример паттерна Flyweight. 01.09.2010

  • 3

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

    Если бы вы написали:

       String s1 = new String ("Hello");
       String s2 = new String ("Hello");
    

    это дало бы вам вывод: «разные строки». Ключевое слово «new» создает новую ссылку на объект, не давая new, сначала проверит пул строк на его существование.

    10.08.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..