Есть два самых популярных способа создания строк:
1 —
String s1 = new String("Hello"); 2 —
String s2 = "Hello"; Разберем отличия.
▪️ 1. Место в памяти (Самое главное отличие) — Это отличие является корнем всех остальных различий.
🔸
String s1 = new String("Hello"); (Оператор new) ➖ Создает новый объект в Куче (Heap), независимо от того, какая строка там уже существует.
➖ Каждый вызов new String("Hello") гарантированно создает новый, уникальный объект в памяти.
🔸
String s2 = "Hello"; (Строковый литерал)➖ Строка создается и помещается в специальную область памяти — String Pool (Пул строк), который находится внутри кучи.
➖ Механизм String Pool: Перед созданием новой строки JVM проверяет, нет ли уже строки с таким же значением в пуле. Если есть — переменной просто присваивается ссылка на существующий объект. Если нет — тогда в пуле создается новый объект.
Наглядная аналогия:
➖ new String("Hello") — покупка нового, уникального экземпляра книги, даже если она уже есть в библиотеке.
➖ "Hello" — взятие книги из библиотеки. Если книга есть — вы получаете именно её. Если нет — библиотека сначала покупает новую, а вы её берете.
▪️ 2. Поведение при сравнении (==). Оператор == сравнивает ссылки на объекты, а не их содержимое. Из-за различий в памяти поведение будет разным.
String s1 = new String("Hello");
String s2 = "Hello";
String s3 = "Hello";
System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // true➖ s1 == s2 -> false, потому что s1 ссылается на объект в куче, а s2 — на объект в String Pool. Это два разных объекта в памяти.
➖ s2 == s3 -> true, потому что обе переменные ссылаются на один и тот же объект в String Pool.
Для сравнения содержимого строк всегда используйте метод equals():
System.out.println(s1.equals(s2)); // true (сравнивается содержимое "Hello")
System.out.println(s2.equals(s3)); // true
▪️ 3. Производительность
🔸Строковый литерал ("Hello") — более эффективен. Он избегает создания дубликатов в памяти, что экономит память и ускоряет работу, так как не нужно создавать новый объект, если он уже существует в пуле.
🔸Оператор new — менее эффективен. Он принудительно создает новый объект в куче, даже если идентичная строка уже существует. Это может привести к избыточному расходу памяти.
▪️ 4. Количество создаваемых объектов
🔸
String s1 = new String("Hello"); — Может создать 1 или 2 объекта.➖ 1. Строковый литерал "Hello" сначала ищется в String Pool. Если его нет — он создается в пуле. (Первый возможный объект).
➖ 2. Затем ключевое слово new создает новый объект String в куче. (Второй объект).
Таким образом, если строка "Hello" ранее не существовала в пуле, эта строка кода создаст два объекта.
🔸
String s2 = "Hello";➖ Создает 0 или 1 объект.
➖ JVM ищет "Hello" в String Pool. Если находит — объект не создается, переменной присваивается существующая ссылка (0 новых объектов).
➖ Если не находит — создает новый объект в String Pool (1 новый объект).
▪️Метод intern() — мостик между двумя подходами. Метод intern() позволяет вручную поместить строку из кучи в String Pool или получить ссылку на уже существующую там строку.
String s1 = new String("Hello");
String s2 = s1.intern(); // Помещаем строку в пул (или получаем ссылку из пула)
String s3 = "Hello";
System.out.println(s1 == s2); // false, т.к. s1 все еще в куче
System.out.println(s2 == s3); // true, т.к. s2 и s3 ссылаются на один объект в пулеВ этом примере
s1.intern() находит строку "Hello" в пуле (которая была создана при вычислении литерала внутри конструктора) и возвращает на неё ссылку, которую мы присваиваем s2.Практический вывод: Почти всегда следует использовать строковые литералы (
String s = "value";). Этот способ более эффективен по памяти и времени, так как использует механизм пула строк. #java #задачи #программирование #собеседования #IT #структуры_данных💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤26👍20🔥7✍2👨💻2❤🔥1⚡1
В Java существует важное правило (контракт):
1. Если две строки равны по
equals(), то их hashCode() ДОЛЖЕН быть одинаковым2. Обратное не обязательно верно: одинаковый
hashCode() не гарантирует равенства строкString s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1.equals(s2)); // true
System.out.println(s1.hashCode() == s2.hashCode()); // true
System.out.println(s1.equals(s3)); // true
System.out.println(s1.hashCode() == s3.hashCode()); // true
Метод hashCode() в классе String вычисляется на основе содержимого строки:
public int hashCode() {
int h = hash; // кэшированное значение
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}➖ Вычисляется по формуле:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]➖ Результат кэшируется в поле hash для производительности
➖ Для одинакового содержимого всегда одинаковый hashCode, независимо от того, как была создана строка
➖ value и hash — являются полями класса String и уже существуют в объекте, когда вызывается метод hashCode().
value — массив символов, который хранит собственно содержимое строки. Он инициализируется при создании объекта.
String s = "Hello"; // value = {'H', 'e', 'l', 'l', 'o'}hash — поле для кэширования вычисленного хэш-кода. Оно инициализируется по умолчанию значением 0.
Практическое применение в коллекциях: Связь hashCode и equals критически важна для работы хэш-коллекций:
🔸 HashMap/HashSet
Map<String, Integer> map = new HashMap<>();
map.put("Hello", 1);
map.put(new String("Hello"), 2); // Затрет предыдущее значение!
System.out.println(map.size()); // 1 - потому что ключи равны по equals()
1. Сначала сравниваются hashCode() — если разные, объекты точно разные
2. Если hashCode одинаковые, тогда вызывается equals() для точной проверки
🔸 Оптимизация сравнения
String s1 = "very long string ...";
String s2 = "another very long string ...";
// Сначала проверяется hashCode - быстрая операция
if (s1.hashCode() == s2.hashCode() && s1.equals(s2)) {
// Строки точно равны
}
▪️ 1. Коллизии хэшей — Разные строки могут иметь одинаковый hashCode (хэш-коллизия)
String a = "Aa";
String b = "BB";
System.out.println(a.hashCode()); // 2112
System.out.println(b.hashCode()); // 2112
System.out.println(a.equals(b)); // false
▪️ 2. Производительность
// Медленно - создается новый объект и вычисляется hashCode
String s1 = new String("Hello");
// Быстро - используется кэшированный hashCode из String Pool
String s2 = "Hello";
3. String Pool и hashCode
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
// Все три имеют одинаковый hashCode, но разные способы создания
System.out.println(s1.hashCode()); // одинаковый
System.out.println(s2.hashCode()); // одинаковый
System.out.println(s3.hashCode()); // одинаковый
🔍 Важные моменты. HashCode тесно связан со сравнением строк через:
1. Контракт Java — равные строки по equals() должны иметь одинаковый hashCode
2.. Оптимизацию сравнения — хэш используется для быстрой предварительной проверки
3. Работу коллекций — HashMap, HashSet и другие используют эту связь для эффективного хранения и поиска
#java #задачи #программирование #собеседования #IT #структуры_данных
💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤27👍22🔥7❤🔥4👨💻3
🔍 Субботняя задачка по физике для разминки наших подписчиков
Вспомним немного оптики. Задачка из дополнительных вступительных испытаний в МГУ.
✍🏻 Попробуйте решить самостоятельно и написать в комментариях ваши идеи. ( Обсуждаем задачу здесь )
#геометрия #оптика #олимпиады #мгу #дви #задачи #problems #физика
💡 Physics.Math.Code // @physics_lib
Вспомним немного оптики. Задачка из дополнительных вступительных испытаний в МГУ.
✍🏻 Попробуйте решить самостоятельно и написать в комментариях ваши идеи. ( Обсуждаем задачу здесь )
#геометрия #оптика #олимпиады #мгу #дви #задачи #problems #физика
💡 Physics.Math.Code // @physics_lib
1👍19❤14✍7🔥7🤯2🤷♀1
По прошлому посту про реактивную горелку один из подписчиков задал очень хороший вопрос:
Зачем собирать такую гарелку-обогреватель, если можно просто сжечь бензин в тарелке и тепла будет столько же.
Действительно ли это так? Один из подвохов здесь заключается в том, что важно не количество тепла, а качество процесса и топлива.
▪️1. Тип топлива и его стоимость (Главный аргумент)
➖ «Просто сжечь бензин»: Вы используете дорогое, высокоочищенное топливо. Это как топить камин долларовыми купюрами — да, тепло будет, но экономически невыгодно.
➖Горелка с эжекцией: Она идеально подходит для сжигания дешевых, низкокачественных и часто бесплатных видов топлива:
— Отработанное моторное масло (отработка). Его просто выбрасывают или дорого утилизируют. Для такой горелки — это идеальное и бесплатное топливо.
— Солярка (дизельное топливо). Дешевле бензина.
— Мазут.
— Растительные масла.
Эта горелка — не про бензин, а про утилизацию отходов и экономию. Вы получаете тепло практически даром.
▪️2. Качество сгорания и безопасность
➖«Просто сжечь бензин»: Вы плеснули бензин в миску и поднесли спичку. Что получится?
Горит открытое горючее тело — чудовищная пожароопасность. Любая искра, перевернутая емкость — и пожар.
Копоть и вредные выбросы. Бензин сгорает неполностью, выделяя сажу и токсичные вещества (угарный газ). Вы будете этим дышать.
➖Горелка с эжекцией:
Топливо предварительно испаряется/распыляется. Проходя по раскаленной трубке, жидкое топливо превращается в пар или мелкодисперсную взвесь. Это смешивается с воздухом и сгорает гораздо полнее.
Пламя стабилизировано. Оно горит на выходе из сопла, а не на поверхности открытой жидкости. Это стабильный, управляемый факел.
Выше температура и КПД. Из-за лучшего смесеобразования КПД такого сжигания (хоть и неидеальный) все равно выше, чем у открытой лужи. (т.е. и расход топлива меньше)
Эта конструкция безопаснее (относительно, конечно) и экологичнее, так как обеспечивает более полное сгорание.
▪️3. Автоматизация и стабильность
«Просто сжечь бензин»: Это одноразовый процесс. Сгорело — и все. Чтобы греть постоянно, нужно постоянно подливать топливо, что неудобно и опасно.
Горелка с эжекцией: Это саморегулирующаяся система. Пламя само подсасывает ровно столько топлива, сколько может испарить и сжечь. Вы залили бак — и она работает стабильно долгое время без вашего участия.
Тепла действительно будет примерно одинаково. Но эта горелка создана для другого:
1. Экономия: Она превращает бесплатные или очень дешевые отходы (отработка) в полезное тепло. Сравнивать нужно не с бензином, а со стоимостью дров, угля или электричества.
2. Эффективность и безопасность: Она сжигает это "грязное" топливо гораздо лучше и безопаснее, чем примитивное открытое горение.
3. Удобство: Это работоспособный, хоть и кустарный, нагревательный прибор, а не просто эксперимент. #задачи #physics #физика #опыты #термодинамика #эксперименты #горение
💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍32❤8🔥6🤔3❤🔥1🤯1🤝1