Чтение YAML в Java
Базовое чтение в Map
Простейший способ — загрузить YAML как вложенную структуру
Метод
Типы маппинга по умолчанию:
Отображения (маппинги) →
Последовательности →
Строки →
Целые числа →
Числа с плавающей точкой →
Булевы →
Null →
Потенциальная проблема: ClassCastException
Базовый подход с
Чтение в объекты: loadAs
SnakeYAML поддерживает маппинг YAML напрямую на Java-объекты через механизм JavaBeans. Для этого используется метод
YAML-файл конфигурации:
Чтение в объект:
SnakeYAML автоматически:
Маппит ключ
Маппит вложенный объект
Маппит YAML-последовательность на
Преобразует строковое значение
Кастомные конструкторы для сложных типов
Когда стандартного маппинга JavaBeans недостаточно — например, нужно преобразовать строку в специфический доменный объект — используются кастомные конструкторы SnakeYAML.
Использование в конфигурации:
#Java #для_новичков #beginner #IO #NIO #Serialize #YAML
Базовое чтение в Map
Простейший способ — загрузить YAML как вложенную структуру
Map и List:import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.util.Map;
import java.util.List;
public class YamlReader {
public Map<String, Object> loadConfig(InputStream input) {
// Yaml — лёгкий объект, но не thread-safe
// Для многопоточного использования создавайте Yaml на каждый поток
Yaml yaml = new Yaml();
// load возвращает Object, который для корневого отображения
// приводится к Map<String, Object>
return yaml.load(input);
}
public void printNestedValue(Map<String, Object> config) {
// YAML-отображения маппятся на LinkedHashMap (сохраняет порядок ключей)
// YAML-последовательности маппятся на ArrayList
Map<String, Object> server = (Map<String, Object>) config.get("server");
Integer port = (Integer) server.get("port");
System.out.println("Port: " + port);
}
}
Метод
load(InputStream) читает YAML-документ и возвращает корневой объект. Типы маппинга по умолчанию:
Отображения (маппинги) →
LinkedHashMap<String, Object>Последовательности →
ArrayList<Object>Строки →
StringЦелые числа →
Integer или Long (в зависимости от размера)Числа с плавающей точкой →
DoubleБулевы →
BooleanNull →
nullLinkedHashMap — это реализация интерфейса Map в Java, которая, в отличие от обычного HashMap, сохраняет порядок вставки элементов. Это важно для YAML, так как порядок ключей в конфигурации часто семантически значим.
Потенциальная проблема: ClassCastException
Базовый подход с
Map<String, Object> требует постоянного приведения типов и не даёт статической типизации. Для глубоко вложенных конфигураций это приводит к громоздкому и ошибкоёмкому коду:// Многоуровневое извлечение значения без типобезопасности
Map<String, Object> db = (Map<String, Object>) config.get("database");
Map<String, Object> pool = (Map<String, Object>) db.get("connectionPool");
Integer maxSize = (Integer) pool.get("maxSize"); // ClassCastException, если тип другой
Чтение в объекты: loadAs
SnakeYAML поддерживает маппинг YAML напрямую на Java-объекты через механизм JavaBeans. Для этого используется метод
loadAs(InputStream, Class<T>).JavaBeans — это соглашение в Java, согласно которому класс должен иметь конструктор без параметров, публичные геттеры и сеттеры для свойств, и реализовывать интерфейс Serializable (опционально). SnakeYAML использует рефлексию для вызова сеттеров по именам ключей YAML.
import org.yaml.snakeyaml.Yaml;
public class LibraryConfig {
private String storagePath;
private int maxBooks;
private DatabaseConfig database;
private List<String> allowedFormats;
// Конструктор по умолчанию обязателен для SnakeYAML
public LibraryConfig() {}
// Геттеры и сеттеры — SnakeYAML вызывает сеттеры по имени ключа
public String getStoragePath() { return storagePath; }
public void setStoragePath(String storagePath) { this.storagePath = storagePath; }
public int getMaxBooks() { return maxBooks; }
public void setMaxBooks(int maxBooks) { this.maxBooks = maxBooks; }
public DatabaseConfig getDatabase() { return database; }
public void setDatabase(DatabaseConfig database) { this.database = database; }
public List<String> getAllowedFormats() { return allowedFormats; }
public void setAllowedFormats(List<String> allowedFormats) { this.allowedFormats = allowedFormats; }
// Вложенный класс конфигурации
public static class DatabaseConfig {
private String url;
private String username;
private String password;
private int connectionTimeout;
public DatabaseConfig() {}
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public int getConnectionTimeout() { return connectionTimeout; }
public void setConnectionTimeout(int connectionTimeout) { this.connectionTimeout = connectionTimeout; }
}
}
YAML-файл конфигурации:
storagePath: /var/lib/library
maxBooks: 10000
allowedFormats:
- epub
- mobi
database:
url: jdbc:postgresql://localhost:5432/library
username: lib_admin
password: secret
connectionTimeout: 30
Чтение в объект:
public class ConfigLoader {
public LibraryConfig loadLibraryConfig(InputStream input) {
Yaml yaml = new Yaml();
// loadAs маппит YAML на объект указанного класса через JavaBeans
return yaml.loadAs(input, LibraryConfig.class);
}
}SnakeYAML автоматически:
Маппит ключ
storagePath на вызов setStoragePath()Маппит вложенный объект
database на инстанцирование LibraryConfig.DatabaseConfigМаппит YAML-последовательность на
List<String>Преобразует строковое значение
"10000" в int через соответствующий сеттерКастомные конструкторы для сложных типов
Когда стандартного маппинга JavaBeans недостаточно — например, нужно преобразовать строку в специфический доменный объект — используются кастомные конструкторы SnakeYAML.
public class CustomDurationConstructor extends Constructor {
public CustomDurationConstructor(Class<?> theRoot) {
super(theRoot);
// Регистрируем кастомный конструктор для тега !duration
this.yamlConstructors.put(new Tag("!duration"), new DurationConstruct());
}
// AbstractConstruct — базовый класс для пользовательских конструкторов узлов YAML
private class DurationConstruct extends AbstractConstruct {
@Override
public Object construct(Node node) {
// ScalarNode представляет скалярное значение (строка, число и т.д.)
String value = ((ScalarNode) node).getValue();
try {
// ISO-8601 формат: PT30S — 30 секунд, PT5M — 5 минут
return Duration.parse(value);
} catch (DateTimeParseException e) {
throw new YAMLException("Невалидный формат Duration: " + value, e);
}
}
}
}Использование в конфигурации:
storagePath: /var/lib/library
maxBooks: 10000
sessionTimeout: !duration PT30M
public class AdvancedConfig {
private Duration sessionTimeout;
public Duration getSessionTimeout() { return sessionTimeout; }
public void setSessionTimeout(Duration sessionTimeout) { this.sessionTimeout = sessionTimeout; }
}
// Загрузка с кастомным конструктором
Yaml yaml = new Yaml(new CustomDurationConstructor(AdvancedConfig.class));
AdvancedConfig config = yaml.load(input);Тег (tag) в YAML — это метка, явно указывающая тип узла. Стандартные теги: !!str , !!int, !!float, !!bool, !!null, !!map, !!seq. Пользовательские теги начинаются с ! (локальные) или !! (глобальные). Теги позволяют YAML-документу нести информацию о типах, необходимую для корректной десериализации.
#Java #для_новичков #beginner #IO #NIO #Serialize #YAML
👍4
Запись YAML из Java
Метод
Поддержка списков, вложенных объектов и многострочных строк
Списки (последовательности)
Вложенные объекты (отображения)
Многострочные строки
YAML предоставляет два оператора для многострочных строк:
Literal block scalar (
Folded block scalar (
Сравнение YAML и JSON для конфигураций
Читаемость
YAML превосходит JSON в читаемости за счёт отсутствия скобок и кавычек. Сравним одинаковую конфигурацию:
JSON:
YAML:
В YAML отсутствуют запятые после каждого элемента, нет обрамляющих скобок, строки не требуют кавычек (кроме случаев, когда значение может быть интерпретировано как другой тип — например,
Комментарии
YAML поддерживает комментарии двумя способами:
YAML не поддерживает многострочные комментарии напрямую, но можно использовать несколько строк с
JSON официально не поддерживает комментарии (RFC 8259). Некоторые парсеры допускают комментарии как расширение, но это нарушает стандарт. Для конфигураций, где комментарии критичны (объяснение значения параметра, временное отключение опции, TODO), YAML является единственным разумным выбором из двух.
Строгость и предсказуемость
JSON более строг и предсказуем: каждый документ — ровно один объект или массив, синтаксис однозначен. YAML имеет сложную спецификацию с множеством особенностей: неявная типизация (
Производительность
JSON парсится быстрее, так как грамматика проще и не требует отслеживания отступов. YAML-парсер должен вычислять отступы каждой строки, обрабатывать сложные правила скаляров и тегов. Для конфигураций, которые читаются один раз при старте приложения, эта разница несущественна. Для высокочастотного обмена данными (миллионы сообщений в секунду) JSON предпочтительнее.
Вывод
Используйте YAML для конфигураций, которые пишут и читают люди:
Используйте JSON для машинно-генерируемых данных, API-контрактов, логов и сценариев, где производительность парсинга критична.
#Java #для_новичков #beginner #IO #NIO #Serialize #YAML
Метод
dump(Object data, Writer writer) сериализует Java-объект в YAML-представление.public class YamlWriter {
public String writeConfig(LibraryConfig config) {
// DumperOptions — настройки форматирования вывода
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); // блочный стиль вместо inline
options.setPrettyFlow(true); // красивые отступы
options.setIndent(2); // отступ в 2 пробела
Yaml yaml = new Yaml(options);
StringWriter writer = new StringWriter();
yaml.dump(config, writer);
return writer.toString();
}
}Flow style и block style — это два способа записи коллекций в YAML. Block style использует отступы (как Python), flow style использует JSON-подобный синтаксис со скобками. Для конфигураций block style предпочтителен из-за читаемости.
Поддержка списков, вложенных объектов и многострочных строк
Списки (последовательности)
allowedFormats:
- epub
- mobi
# Альтернативный flow-style (менее читаемый)
allowedFormats: [pdf, epub, mobi]
Вложенные объекты (отображения)
database:
url: jdbc:postgresql://localhost:5432/library
pool:
min: 5
max: 20
Многострочные строки
YAML предоставляет два оператора для многострочных строк:
Literal block scalar (
|): сохраняет переводы строки как есть.Folded block scalar (
>): заменяет одиночные переводы строки пробелами, сохраняя только пустые строки как разделители абзацев.description: |
Это многострочный текст.
Каждая строка сохраняет свой перевод.
Итоговая строка содержит \n между строками.
license: >
Это текст, который в исходном YAML
разбит на строки для читаемости,
но в результирующей строке будет
представлен одним абзацем с пробелами
вместо переводов строк.
Block scalar — это способ записи скалярных значений (строк), занимающих несколько строк, в YAML. Оператор (pipe) используется для verbatim (дословного) сохранения строк, оператор > (greater-than) — для сворачивания строк в один абзац.
Сравнение YAML и JSON для конфигураций
Читаемость
YAML превосходит JSON в читаемости за счёт отсутствия скобок и кавычек. Сравним одинаковую конфигурацию:
JSON:
{
"server": {
"port": 8080,
"ssl": {
"enabled": true,
"certificate": "/etc/ssl/cert.pem"
}
},
"features": ["auth", "logging", "metrics"]
}YAML:
server:
port: 8080
ssl:
enabled: true
certificate: /etc/ssl/cert.pem
features:
- auth
- logging
- metrics
В YAML отсутствуют запятые после каждого элемента, нет обрамляющих скобок, строки не требуют кавычек (кроме случаев, когда значение может быть интерпретировано как другой тип — например,
"true" как строка vs true как булево). Это снижает визуальный шум и упрощает ревью изменений в системах контроля версий.Комментарии
YAML поддерживает комментарии двумя способами:
# — однострочный комментарий до конца строки.YAML не поддерживает многострочные комментарии напрямую, но можно использовать несколько строк с
#.JSON официально не поддерживает комментарии (RFC 8259). Некоторые парсеры допускают комментарии как расширение, но это нарушает стандарт. Для конфигураций, где комментарии критичны (объяснение значения параметра, временное отключение опции, TODO), YAML является единственным разумным выбором из двух.
Строгость и предсказуемость
JSON более строг и предсказуем: каждый документ — ровно один объект или массив, синтаксис однозначен. YAML имеет сложную спецификацию с множеством особенностей: неявная типизация (
yes может быть интерпретировано как булево true в YAML 1.1), якоря и алиасы (&anchor и *alias), сложные правила отступов. Это делает YAML более подверженным ошибкам при ручном редактировании: лишний пробел может изменить структуру, а неявная типизация — привести к неожиданным значениям.Якорь (anchor) и алиас (alias) — это механизм YAML для повторного использования узлов. &name создаёт якорь для узла, *name создаёт ссылку (алиас) на этот узел. Это позволяет избежать дублирования, но усложняет документ.
Производительность
JSON парсится быстрее, так как грамматика проще и не требует отслеживания отступов. YAML-парсер должен вычислять отступы каждой строки, обрабатывать сложные правила скаляров и тегов. Для конфигураций, которые читаются один раз при старте приложения, эта разница несущественна. Для высокочастотного обмена данными (миллионы сообщений в секунду) JSON предпочтительнее.
Вывод
Используйте YAML для конфигураций, которые пишут и читают люди:
application.yml, CI/CD пайплайны, Kubernetes-манифесты.Используйте JSON для машинно-генерируемых данных, API-контрактов, логов и сценариев, где производительность парсинга критична.
#Java #для_новичков #beginner #IO #NIO #Serialize #YAML
👍4
Путь байтов в памяти JVM при работе с YAML
1. Загрузка YAML-файла
Когда приложение читает
Файл считывается через
SnakeYAML использует
Парсер SnakeYAML читает символы и строит внутреннее представление документа — дерево узлов (Node graph). Каждый узел YAML (скаляр, последовательность, отображение) представлен объектом в куче:
2. Маппинг на Java-объекты
После построения дерева узлов начинается фаза конструирования:
Для каждого ключа отображения
Значения узлов преобразуются в целевые типы: строки остаются строками, числа конвертируются через
Промежуточные структуры — дерево узлов, массивы символов, объекты рефлексии — становятся мусором после завершения конструирования. Если конфигурация читается один раз при старте приложения, все эти объекты собираются при первой Minor GC после инициализации.
3. Работа GC с конфигурационными объектами
Объект конфигурации (например,
Промежуточные объекты парсинга (дерево узлов,
4. Потенциальная утечка: кэш классов SnakeYAML
SnakeYAML кэширует
5. Запись YAML: обратный путь
При сериализации Java-объекта в YAML:
Байты уходят в файловую систему или сетевой сокет через системные вызовы ОС.
Все промежуточные структуры (дерево узлов, буферы символов) создаются в Young Generation и собираются при следующей Minor GC.
#Java #для_новичков #beginner #IO #NIO #Serialize #YAML
1. Загрузка YAML-файла
Когда приложение читает
application.yml из classpath или файловой системы, данные проходят следующий путь:Файл считывается через
InputStream — байты передаются из кэша страниц ОС через нативную память в буфер byte[] в куче JVM (аналогично Files.readAllBytes(), описанному в предыдущих уроках).SnakeYAML использует
Reader (обычно InputStreamReader с кодировкой UTF-8) для декодирования байтов в символы char[]. Этот массив создаётся в Young Generation, в Eden.Парсер SnakeYAML читает символы и строит внутреннее представление документа — дерево узлов (Node graph). Каждый узел YAML (скаляр, последовательность, отображение) представлен объектом в куче:
ScalarNode, MappingNode, SequenceNode. Для конфигурации размером 5 КБ количество узлов может достигать нескольких десятков.Node graph — это промежуточное представление YAML-документа в памяти парсера перед маппингом на Java-объекты. Оно отражает структуру документа независимо от целевого типа данных.
2. Маппинг на Java-объекты
После построения дерева узлов начинается фаза конструирования:
Constructor обходит дерево узлов. Для каждого MappingNode он создаёт целевой Java-объект через рефлексию: вызов Class.newInstance() (или Constructor.newInstance() в современных версиях) аллоцирует объект в куче.Для каждого ключа отображения
Constructor ищет соответствующий сеттер через Introspector (механизм JavaBeans introspection). Introspector анализирует класс и кэширует PropertyDescriptor — дескрипторы свойств. Эти дескрипторы создаются при первом обращении к классу и хранятся в кэше, но первое использование класса порождает множество временных объектов рефлексии.Introspection (интроспекция) — это механизм Java, позволяющий во время выполнения анализировать структуру классов: получать список методов, полей, конструкторов, аннотаций. java.beans.Introspector — стандартный класс для JavaBeans-интроспекции.
Значения узлов преобразуются в целевые типы: строки остаются строками, числа конвертируются через
Integer.parseInt() или аналогичные методы, вложенные отображения рекурсивно конструируются.Промежуточные структуры — дерево узлов, массивы символов, объекты рефлексии — становятся мусором после завершения конструирования. Если конфигурация читается один раз при старте приложения, все эти объекты собираются при первой Minor GC после инициализации.
3. Работа GC с конфигурационными объектами
Объект конфигурации (например,
LibraryConfig) обычно сохраняется в Old Generation (Tenured), так как он живёт всё время жизни приложения. Ссылки на него хранятся в контексте Spring (singleton-бины) или в статических полях.Singleton — это паттерн проектирования, гарантирующий, что у класса есть только один экземпляр, и предоставляющий глобальную точку доступа к нему. В Spring Boot все бины по умолчанию — singleton.
Промежуточные объекты парсинга (дерево узлов,
char[] исходного файла, временные объекты рефлексии) создаются в Young Generation и уничтожаются Minor GC. Важно, что SnakeYAML не использует пул строк для ключей YAML — каждый ключ создаётся как новый объект String в куче. При большом количестве ключей это создаёт давление на Eden, но так как конфигурация читается редко, это не критично.4. Потенциальная утечка: кэш классов SnakeYAML
SnakeYAML кэширует
TypeDescription и конструкторы классов во внутренних Map. Эти кэши растут по мере обработки новых классов. В долгоживущих приложениях, которые динамически загружают множество различных YAML-схем, кэш может занимать значительный объём Old Generation. Это не утечка в классическом смысле (кэш необходим), но требует мониторинга через heap dump.Heap dump — это снимок всей кучи JVM в определённый момент времени. Он содержит все объекты, их размеры, ссылки между ними и классы. Анализ heap dump позволяет находить утечки памяти и понимать распределение объектов по поколениям.
5. Запись YAML: обратный путь
При сериализации Java-объекта в YAML:
Representer обходит поля объекта и строит дерево узлов в памяти (аллокации в Young Generation).Emitter преобразует дерево узлов в поток символов char[].Writer кодирует символы в UTF-8 байты и записывает в OutputStream.Байты уходят в файловую систему или сетевой сокет через системные вызовы ОС.
Все промежуточные структуры (дерево узлов, буферы символов) создаются в Young Generation и собираются при следующей Minor GC.
#Java #для_новичков #beginner #IO #NIO #Serialize #YAML
👍4
Всем привет!
Запустил тестово нового бота @Review_Trainer_Bot. Если интересно - можете пощупать руками)))
Запустил тестово нового бота @Review_Trainer_Bot. Если интересно - можете пощупать руками)))
🔥5
Что выведет код?
#Tasks
import org.yaml.snakeyaml.Yaml;
import java.util.Map;
public class Task060826 {
public static void main(String[] args) {
String yaml = "enabled: on\nvalue: 010";
Yaml yamlParser = new Yaml();
Map<String, Object> data = yamlParser.load(yaml);
System.out.println(data.get("enabled") + ", " + data.get("value"));
}
}
#Tasks
👍2
👍2
Что такое аннотация 🤓
Ответ:
Аннотация @FunctionalInterface указывает компилятору, что интерфейс должен содержать ровно один абстрактный метод.
Она не обязательна, но рекомендуется для документирования намерения. Если в интерфейсе больше одного абстрактного метода, компилятор выдаст ошибку.
Эта аннотация используется в лямбда-выражениях и ссылках на методы. Пример: Runnable, Comparator, Predicate, Consumer.
Помогает избежать случайных изменений в интерфейсах, которые сломают лямбда-совместимость.
#собеседование
@FunctionalInterface и зачем она нужна? Ответ:
Она не обязательна, но рекомендуется для документирования намерения. Если в интерфейсе больше одного абстрактного метода, компилятор выдаст ошибку.
Эта аннотация используется в лямбда-выражениях и ссылках на методы. Пример: Runnable, Comparator, Predicate, Consumer.
Помогает избежать случайных изменений в интерфейсах, которые сломают лямбда-совместимость.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Java for Beginner
Всем привет! Запустил тестово нового бота @Review_Trainer_Bot. Если интересно - можете пощупать руками)))
Ребят вижу что 10 человек попробовало бота.
Не поленитесь - напишите фидбек?
Как вам, чего не хватает, что не интересно и так далее?
Благодарен за любое мнение)))
Не поленитесь - напишите фидбек?
Как вам, чего не хватает, что не интересно и так далее?
Благодарен за любое мнение)))
👍2
История технологии сегодня — 07 августа
ℹ️ Кто родился в этот день
Джи́мми До́нал Уэ́йлс (англ. Jimmy Donal Wales, также известный под псевдонимом Джи́мбо (англ. Jimbo); род. 7 августа 1966, Хантсвилл, Алабама) — американский и британский интернет-предприниматель, идеолог концепции вики, основатель Википедии, председатель Фонда Викимедиа (2003—2006). С лета 2011 года — почётный председатель Фонда Викимедиа; директор компании Fandom (ранее — Wikia).
🌐 Знаковые события
1944 — запущен первый американский программируемый компьютер «Марк I».
1970 — проведён первый компьютерный шахматный турнир.
#Biography #Birth_Date #Events #07августа
Джи́мми До́нал Уэ́йлс (англ. Jimmy Donal Wales, также известный под псевдонимом Джи́мбо (англ. Jimbo); род. 7 августа 1966, Хантсвилл, Алабама) — американский и британский интернет-предприниматель, идеолог концепции вики, основатель Википедии, председатель Фонда Викимедиа (2003—2006). С лета 2011 года — почётный председатель Фонда Викимедиа; директор компании Fandom (ранее — Wikia).
1944 — запущен первый американский программируемый компьютер «Марк I».
1970 — проведён первый компьютерный шахматный турнир.
#Biography #Birth_Date #Events #07августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
[Совет по Java #069]
Тема: Всегда переопределяйте
Проблема: Интерфейс
Если это правило нарушено, то
Решение: При реализации
Для этого используйте в
Для примитивных полей используйте
Объяснение:
При этом
Это нарушает принцип "Set не содержит дубликатов" — фактически дубликаты по
#Java #советы
Тема: Всегда переопределяйте
compareTo() в соответствии с equals(), если планируете использовать объекты в TreeSet/TreeMap.Проблема: Интерфейс
Comparable и его метод compareTo() определяют естественный порядок объектов. Контракт Comparable требует, чтобы compareTo() был согласован с equals(), то есть для любых двух объектов a и b должно выполняться: a.compareTo(b) == 0 тогда и только тогда, когда a.equals(b) == true. Если это правило нарушено, то
TreeSet и TreeMap, которые используют compareTo() для сравнения и упорядочивания, перестают корректно работать. Например, если два объекта имеют одинаковый compareTo (возвращают 0), но разные equals, они будут считаться дубликатами, и второй не будет добавлен в TreeSet, либо TreeMap перезапишет значение. Это противоречит ожиданиям, основанным на equals. Ошибка проявляется в виде "потери" элементов, неправильного размера множества или некорректного поиска по ключу.Решение: При реализации
Comparable для классов, которые будут использоваться в упорядоченных коллекциях, всегда проверяйте, что compareTo возвращает 0 для объектов, которые считаются равными по equals. Для этого используйте в
compareTo те же поля, что и в equals, и в одинаковом порядке. Если поля не могут быть сравнимы (например, null), обработайте это явно. Если невозможно достичь согласованности (например, у вас сложная логика сравнения), используйте отдельный Comparator с четкой документацией, но лучше пересмотреть дизайн. Для примитивных полей используйте
Integer.compare, Double.compare и т.д. Для строк — String.compareTo. Также помните, что compareTo должно быть транзитивным и антисимметричным.import java.util.Objects;
public class Person implements Comparable<Person> {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//Нарушение: compareTo не согласован с equals
// @Override
// public int compareTo(Person o) {
// return this.age - o.age; // Только по возрасту
// }
// // equals по имени и возрасту
// public boolean equals(Object o) {
// if (!(o instanceof Person)) return false;
// Person p = (Person) o;
// return name.equals(p.name) && age == p.age;
// }
//Корректно: compareTo использует те же поля, что и equals
@Override
public int compareTo(Person o) {
int nameComp = this.name.compareTo(o.name);
if (nameComp != 0) return nameComp;
return Integer.compare(this.age, o.age);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person p = (Person) o;
return age == p.age && name.equals(p.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return name + "(" + age + ")";
}
public static void main(String[] args) {
// Демонстрация нарушения
Person p1 = new Person("Alice", 30);
Person p2 = new Person("Bob", 30);
// Если compareTo только по возрасту, то p1.compareTo(p2) == 0,
// хотя equals вернет false (имена разные).
// TreeSet считает их одинаковыми
TreeSet<Person> set = new TreeSet<>();
set.add(p1);
set.add(p2);
System.out.println("Size: " + set.size()); // Должно быть 1, если compareTo=0
System.out.println("Contains Alice? " + set.contains(p1)); // true
System.out.println("Contains Bob? " + set.contains(p2)); // true? Зависит от реализации
// На самом деле, если compareTo=0, то при добавлении второго он будет считаться дубликатом
// и не будет добавлен, но contains для Bob вернет true, потому что TreeSet использует compareTo
// для поиска, а не equals. Это делает поведение непредсказуемым.
}
}
Объяснение:
TreeSet и TreeMap хранят элементы в красно-черном дереве, где сравнение выполняется через compareTo или Comparator. При добавлении элемента дерево проверяет, существует ли уже узел с тем же значением compareTo (т.е. возвращает 0). Если существует, то новый элемент считается дубликатом, и в TreeSet он не добавляется, а в TreeMap перезаписывается значение. При этом
equals вообще не используется для проверки дубликатов; она применяется только для contains и remove? На самом деле, TreeSet использует compareTo для поиска: если compareTo возвращает 0, объект считается равным, и возвращается существующий, без вызова equals. Поэтому нарушение контракта приводит к тому, что объекты, которые по логике должны быть разными, становятся неразличимыми для коллекции. Это нарушает принцип "Set не содержит дубликатов" — фактически дубликаты по
equals могут быть, но они не добавляются из-за compareTo. И наоборот, объекты с одинаковым equals, но разным compareTo, будут восприниматься как разные, что нарушает контракт Set. Поэтому всегда используйте в compareTo те же поля, что и в equals, и в том же порядке, чтобы обеспечить согласованность. Если поля могут быть null, используйте Objects.compare или явные проверки.#Java #советы
👍3
Что выведет код?
#Tasks
import java.util.TreeSet;
public class Task070826 {
static class Person070826 implements Comparable<Person070826> {
String name;
int age;
Person070826(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person070826 o) {
return Integer.compare(this.age, o.age); // только по возрасту
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person070826)) return false;
Person070826 p = (Person070826) o;
return age == p.age && name.equals(p.name);
}
@Override
public int hashCode() {
return 31 * name.hashCode() + age;
}
}
public static void main(String[] args) {
TreeSet<Person070826> set = new TreeSet<>();
Person070826 p1 = new Person070826("Alice", 25);
Person070826 p2 = new Person070826("Bob", 25);
set.add(p1);
set.add(p2);
System.out.println(set.contains(p1));
System.out.println(set.contains(p2));
System.out.println(set.size());
}
}
#Tasks
👍2
👍3
Java for Beginner
Ребят вижу что 10 человек попробовало бота. Не поленитесь - напишите фидбек? Как вам, чего не хватает, что не интересно и так далее? Благодарен за любое мнение)))
Сколько комментов!))) Аж не успеваю читать)))
👍2
Что такое 🤓
Ответ:
@Autowired — это аннотация Spring для внедрения зависимостей (Dependency Injection).
Может применяться к конструкторам, сеттерам, полям и методам. Spring сканирует контекст и находит бин соответствующего типа.
Если найдено несколько бинов одного типа, используется @Qualifier или @Primary . Начиная с Spring 4.3, @Autowired для конструктора можно не писать, если у класса один конструктор.
Лучшая практика — внедрение через конструктор (для неизменяемых зависимостей и тестируемости).
#собеседование
@Autowired в Spring и как он работает? Ответ:
Может применяться к конструкторам, сеттерам, полям и методам. Spring сканирует контекст и находит бин соответствующего типа.
Если найдено несколько бинов одного типа, используется
Лучшая практика — внедрение через конструктор (для неизменяемых зависимостей и тестируемости).
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологии сегодня — 08 августа
ℹ️ Кто родился в этот день
Михаил Владимирович Донской (8 августа 1948 — 13 января 2009, Москва) — российский программист и предприниматель, один из создателей шахматной программы «Каисса» — первого чемпиона мира среди шахматных программ (1974 год), создатель и глава информационно-технологической компании «ДИСКо».
Ро́джер Пенро́уз (англ. Roger Penrose; род. 8 августа 1931, Колчестер, Англия) — британский физик и математик, работающий в различных областях математики, общей теории относительности и квантовой теории; автор теории твисторов. Нобелевская премия по физике (2020) «за открытие того, что образование чёрных дыр с необходимостью следует из общей теории относительности».
Поль Адриен Морис Дира́к (англ. Paul Adrien Maurice Dirac; 8 августа 1902, Бристоль — 20 октября 1984, Таллахасси) — британский физик-теоретик, один из создателей квантовой механики. Лауреат Нобелевской премии по физике 1933 года (совместно с Эрвином Шрёдингером). Работы Дирака посвящены квантовой физике, теории элементарных частиц, общей теории относительности. Он является автором основополагающих трудов по квантовой механике (общая теория преобразований), квантовой электродинамике (метод вторичного квантования и многовременной формализм) и квантовой теории поля (квантование систем со связями). Предложенное им релятивистское уравнение электрона позволило естественным образом объяснить спин и ввести представление об античастицах.
Эрнест Орландо Ло́уренс (англ. Ernest Orlando Lawrence; 8 августа 1901, Кантон, Южная Дакота, США — 27 августа 1958, Пало-Алто, Калифорния, США) — американский физик-ядерщик, создатель первого циклотрона (1930), за что он был удостоен Нобелевской премии (1939). Проводил исследования по ядерной физике и принимал участие в создании атомной бомбы.
🌐 Знаковые события
1899 — американский изобретатель из Миннесоты Альберт Маршалл запатентовал холодильник.
#Biography #Birth_Date #Events #08августа
Михаил Владимирович Донской (8 августа 1948 — 13 января 2009, Москва) — российский программист и предприниматель, один из создателей шахматной программы «Каисса» — первого чемпиона мира среди шахматных программ (1974 год), создатель и глава информационно-технологической компании «ДИСКо».
Ро́джер Пенро́уз (англ. Roger Penrose; род. 8 августа 1931, Колчестер, Англия) — британский физик и математик, работающий в различных областях математики, общей теории относительности и квантовой теории; автор теории твисторов. Нобелевская премия по физике (2020) «за открытие того, что образование чёрных дыр с необходимостью следует из общей теории относительности».
Поль Адриен Морис Дира́к (англ. Paul Adrien Maurice Dirac; 8 августа 1902, Бристоль — 20 октября 1984, Таллахасси) — британский физик-теоретик, один из создателей квантовой механики. Лауреат Нобелевской премии по физике 1933 года (совместно с Эрвином Шрёдингером). Работы Дирака посвящены квантовой физике, теории элементарных частиц, общей теории относительности. Он является автором основополагающих трудов по квантовой механике (общая теория преобразований), квантовой электродинамике (метод вторичного квантования и многовременной формализм) и квантовой теории поля (квантование систем со связями). Предложенное им релятивистское уравнение электрона позволило естественным образом объяснить спин и ввести представление об античастицах.
Эрнест Орландо Ло́уренс (англ. Ernest Orlando Lawrence; 8 августа 1901, Кантон, Южная Дакота, США — 27 августа 1958, Пало-Алто, Калифорния, США) — американский физик-ядерщик, создатель первого циклотрона (1930), за что он был удостоен Нобелевской премии (1939). Проводил исследования по ядерной физике и принимал участие в создании атомной бомбы.
1899 — американский изобретатель из Миннесоты Альберт Маршалл запатентовал холодильник.
#Biography #Birth_Date #Events #08августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
В бота добавил еще 3 задачи!
Каждого уровня по одной) Дерзайте и делитесь результатами в специальной группе бота. Ссылка в вкладке "от автора".
@Review_Trainer_Bot
@Oleborn
Каждого уровня по одной) Дерзайте и делитесь результатами в специальной группе бота. Ссылка в вкладке "от автора".
@Review_Trainer_Bot
@Oleborn
👍4
История технологии сегодня — 09 августа
ℹ️ Кто родился в этот день
Ма́рвин Ли Ми́нский (англ. Marvin Lee Minsky; 9 августа 1927 — 24 января 2016) — американский учёный в области искусственного интеллекта, сооснователь Лаборатории искусственного интеллекта в Массачусетском технологическом институте.
Никола́й Си́дорович Хло́пкин (9 августа 1923, село Ильинка, Владимирская губерния — 19 декабря 2012, Москва) — советский и российский учёный, доктор технических наук, специалист в области ядерной энергетики и теплофизики.
Анато́лий Ива́нович Кито́в (9 августа 1920, Самара — 14 октября 2005, Москва) — советский и российский учёный, пионер советской кибернетики и информатики, разработчик электронно-вычислительной техники в СССР.
Уи́льям А́лфред Фа́улер (англ. William Alfred Fowler; 9 августа 1911, Питтсбург, Пенсильвания, США — 14 марта 1995, Пасадина, Калифорния, США) — американский физик и астрофизик. Лауреат Нобелевской премии по физике 1983 года — «за теоретическое и экспериментальное исследование ядерных реакций, имеющих важное значение для образования химических элементов Вселенной».
Эрих Арманд Артур Йозеф Хюккель (нем. Erich Armand Arthur Joseph Hückel; 9 августа 1896, Берлин — 16 февраля 1980, Марбург) — немецкий учёный, физик и химик, один из основоположников квантовой химии, создатель теории сильных электролитов (совместно с П. Дебаем).
🌐 Знаковые события
1859 — американец Натан Эймс (Nathan Ames) запатентовал эскалатор.
1910 — американец из Чикаго Альва Джон Фишер запатентовал электрическую стиральную машину.
#Biography #Birth_Date #Events #09августа
Ма́рвин Ли Ми́нский (англ. Marvin Lee Minsky; 9 августа 1927 — 24 января 2016) — американский учёный в области искусственного интеллекта, сооснователь Лаборатории искусственного интеллекта в Массачусетском технологическом институте.
Никола́й Си́дорович Хло́пкин (9 августа 1923, село Ильинка, Владимирская губерния — 19 декабря 2012, Москва) — советский и российский учёный, доктор технических наук, специалист в области ядерной энергетики и теплофизики.
Анато́лий Ива́нович Кито́в (9 августа 1920, Самара — 14 октября 2005, Москва) — советский и российский учёный, пионер советской кибернетики и информатики, разработчик электронно-вычислительной техники в СССР.
Уи́льям А́лфред Фа́улер (англ. William Alfred Fowler; 9 августа 1911, Питтсбург, Пенсильвания, США — 14 марта 1995, Пасадина, Калифорния, США) — американский физик и астрофизик. Лауреат Нобелевской премии по физике 1983 года — «за теоретическое и экспериментальное исследование ядерных реакций, имеющих важное значение для образования химических элементов Вселенной».
Эрих Арманд Артур Йозеф Хюккель (нем. Erich Armand Arthur Joseph Hückel; 9 августа 1896, Берлин — 16 февраля 1980, Марбург) — немецкий учёный, физик и химик, один из основоположников квантовой химии, создатель теории сильных электролитов (совместно с П. Дебаем).
1859 — американец Натан Эймс (Nathan Ames) запатентовал эскалатор.
1910 — американец из Чикаго Альва Джон Фишер запатентовал электрическую стиральную машину.
#Biography #Birth_Date #Events #09августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Наш "Темный попутчик"
Наверное у всех происходила ситуация, когда в выходной день, специально выделив время, ты садишься изучить новый фреймворк (или что угодно), открываешь видос или статью и...
“О, уведомление в телефоне, хм...”
“Пойду налью кофе/чай/вискарика, а то не сосредоточусь”
“Так, а может завтра тоже есть время?”
И вот он уже рядом. Сел поудобнее рядом и улыбается.
Тёмный попутчик - ПРОКРАСТИНАЦИЯ🏝
Но на самом деле, все не так страшно ☺️
Давай разбираться😉
Прокрастинация — это не лень ❗️
Серьёзно.
Если бы это была просто лень — ты бы не испытывал вину за бездействие.
Ты бы не планировал, не страдал, не искал решения.
То есть ты откладываешь не потому что «плохо спланировал день», а потому что в моменте задача вызывает дискомфорт, страх, перфекционизм или даже неосознанную тревогу провала.
(И мозг такой: “А может не надо испытывать всё это прямо сейчас?.. Давай YouTube-чик?..”)
Ты можешь спросить: Это как «Синдром самозванца» из предыдущей статьи?
Да.
И они очень часто идут рука об руку. 🤝
Синдром самозванца шепчет тебе: "Ты не справишься. Ты недостаточно хорош. Это не для тебя".
А прокрастинация отвечает: "Окей! Давай немного отложим! На потом! А пока посмотрим видосы про котиков".🆘
Сочетание этих двух — вражеский тандем внутри твоей головы. Один пугает, другой уводит от страха. В итоге ты вроде и не бездельничаешь (ну, ты же чем-то занят!), но никуда не продвигаешься.
❓ И что делать-то? ❓
1. Принять, что это НОРМАЛЬНО.
Если ты осознал, что прокрастинируешь — не страшно. Я, ты, даже суперуспешные программисты — все откладывают. Просто надо научиться держать этот хаос под контролем.🧑💻
2. Обманывать мозг.
Сказать себе: “Сделаю 10 минут, и всё, можно будет отдыхать”. И, о чудо — через 30 минут ты уже глубоко в дебрях кода.
Это называется “техника маленьких шагов” — не грузить себя “большой задачей”, а начинать с малого. Упростить задачу, выбрав, что полегче и начать.
Работает почти всегда.
3. Выбери что-то одно.
Когда у тебя открыто множество обучающих вкладок: “Выучить Spring”, “Новое по Hibernate” или новая статья на канале “ Java for Beginner” — угадай, чем всё закончится? Правильно: YouTube, котики и стирка носков.
Выбери ОДНО и делай. Остальное — в «позже» (а может и в "нафиг"...☺️ ).
4. Используй "tecnica del pomodoro"
25 минут работаешь, 5 отдыхаешь. Простой трюк, но мозгу легче "терпеть" неприятное, если знает, что скоро — пауза.
Это методика из когнитивно-поведенческой психологии — дробление задач снижает тревожность.
Но главное: не жди, что мотивация заняться задачей появится.🤫
Если честно — мотивация в 90% случаев НЕ приходит.
Если прокрастинация в разгаре, то можно провалиться в окончательную лень и перестать бороться.
Начинать нужно без неё. Начинать нужно через "нехочу".
А вот когда пошел процесс, когда что-то получилось — появляется и мотивация.
Старт → действие → результат → мотивация.
Прокрастинация — не отсутствие силы воли. Это просто неправильный диалог с собой.
Мозг не против работать. Он просто не хочет страдать.
Договорись с темным попутчиком, обмани, разбей задачу, убери лишние эмоции — и действуй.
А теперь — иди и начни делать то, что откладывал, прокрастинируя и залипая в эту статью!💪
😎
#motivation
Наверное у всех происходила ситуация, когда в выходной день, специально выделив время, ты садишься изучить новый фреймворк (или что угодно), открываешь видос или статью и...
“О, уведомление в телефоне, хм...”
“Пойду налью кофе/чай/вискарика, а то не сосредоточусь”
“Так, а может завтра тоже есть время?”
И вот он уже рядом. Сел поудобнее рядом и улыбается.
Тёмный попутчик - ПРОКРАСТИНАЦИЯ
Давай разбираться
Прокрастинация — это не лень ❗️
Серьёзно.
Если бы это была просто лень — ты бы не испытывал вину за бездействие.
Ты бы не планировал, не страдал, не искал решения.
С научной точки зрения, прокрастинация — это иррациональное откладывание дел, сопровождающееся стрессом, тревожностью, и часто — сниженной самооценкой.
"Прокрастинация — это не проблема управления временем. Это проблема управления эмоциями."
— Тимоти Пихл, профессор психологии, автор исследований по теме.
То есть ты откладываешь не потому что «плохо спланировал день», а потому что в моменте задача вызывает дискомфорт, страх, перфекционизм или даже неосознанную тревогу провала.
(И мозг такой: “А может не надо испытывать всё это прямо сейчас?.. Давай YouTube-чик?..”)
Ты можешь спросить: Это как «Синдром самозванца» из предыдущей статьи?
Да.
И они очень часто идут рука об руку. 🤝
Синдром самозванца шепчет тебе: "Ты не справишься. Ты недостаточно хорош. Это не для тебя".
А прокрастинация отвечает: "Окей! Давай немного отложим! На потом! А пока посмотрим видосы про котиков".
Сочетание этих двух — вражеский тандем внутри твоей головы. Один пугает, другой уводит от страха. В итоге ты вроде и не бездельничаешь (ну, ты же чем-то занят!), но никуда не продвигаешься.
Откуда приходит прокрастинация?
Психологи выделяют несколько корней прокрастинации:⏺ Эмоциональное избегание – когда ты еще не начал задачу, но уже стрессуешь, что она сложная и ты не справишься. И вместо поиска решения, залипаешь в тик-ток.⏺ Перфекционизм – когда задача кажется слишком важной, и хочется сделать ее «идеально». Но идеал недостижим → страшно, что не получится → откладываем.⏺ Низкая саморегуляция – отсутствие способности справляться с своими внутренними импульсами. Ты просто не можешь заставить себя сесть за задачу.
1. Принять, что это НОРМАЛЬНО.
Если ты осознал, что прокрастинируешь — не страшно. Я, ты, даже суперуспешные программисты — все откладывают. Просто надо научиться держать этот хаос под контролем.
2. Обманывать мозг.
Сказать себе: “Сделаю 10 минут, и всё, можно будет отдыхать”. И, о чудо — через 30 минут ты уже глубоко в дебрях кода.
Это называется “техника маленьких шагов” — не грузить себя “большой задачей”, а начинать с малого. Упростить задачу, выбрав, что полегче и начать.
Работает почти всегда.
3. Выбери что-то одно.
Когда у тебя открыто множество обучающих вкладок: “Выучить Spring”, “Новое по Hibernate” или новая статья на канале “ Java for Beginner” — угадай, чем всё закончится? Правильно: YouTube, котики и стирка носков.
Выбери ОДНО и делай. Остальное — в «позже» (а может и в "нафиг"...
4. Используй "tecnica del pomodoro"
25 минут работаешь, 5 отдыхаешь. Простой трюк, но мозгу легче "терпеть" неприятное, если знает, что скоро — пауза.
Это методика из когнитивно-поведенческой психологии — дробление задач снижает тревожность.
Но главное: не жди, что мотивация заняться задачей появится.
Если честно — мотивация в 90% случаев НЕ приходит.
Если прокрастинация в разгаре, то можно провалиться в окончательную лень и перестать бороться.
Начинать нужно без неё. Начинать нужно через "нехочу".
А вот когда пошел процесс, когда что-то получилось — появляется и мотивация.
Старт → действие → результат → мотивация.
Прокрастинация — не отсутствие силы воли. Это просто неправильный диалог с собой.
Мозг не против работать. Он просто не хочет страдать.
Договорись с темным попутчиком, обмани, разбей задачу, убери лишние эмоции — и действуй.
А теперь — иди и начни делать то, что откладывал, прокрастинируя и залипая в эту статью!
#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10
История технологии сегодня — 10 августа
ℹ️ Кто родился в этот день
Алекса́ндр Григо́рьевич Столе́тов (29 июля [10 августа] 1839, Владимир — 16 [28] мая 1896, Москва) — русский физик, заслуженный профессор Императорского Московского университета.
Получил кривую намагничивания железа (1872), систематически исследовал внешний фотоэффект (1888—1890), открыл первый закон фотоэффекта. Исследовал газовый разряд, критическое состояние и другие явления. Основал физическую лабораторию в Императорском Московском университете.
Во́льфганг Па́уль (нем. Wolfgang Paul, МФА: [ˈvɔlfɡaŋ ˈpaʊ̯l]о файле; 10 августа 1913, Лоренцкирх[вд], Саксония — 7 декабря 1993, Бонн, Северный Рейн-Вестфалия) — немецкий физик, профессор, лауреат Нобелевской премии по физике в 1989 году (половина премии совместно с Хансом Демельтом) «за разработку метода удержания одиночных ионов». Вторую половину премии получил Норман Рамзей «за изобретение метода раздельных колебательных полей и его использование в водородном мазере и других атомных часах».
Луис Брюс (англ. Louis E. Brus — Луис Юджин Брус; 10 августа 1943, Кливленд, США — 11 января 2026) — американский физик, специалист по физической химии. Пионер в области квантовых точек. Лауреат Нобелевской премии по химии (2023).
🌐 Знаковые события
2004 — телескоп Хаббл обнаружил галактику NGC3949, похожую на Млечный путь, и лишился одного из видеосенсоров.
#Biography #Birth_Date #Events #10августа
Алекса́ндр Григо́рьевич Столе́тов (29 июля [10 августа] 1839, Владимир — 16 [28] мая 1896, Москва) — русский физик, заслуженный профессор Императорского Московского университета.
Получил кривую намагничивания железа (1872), систематически исследовал внешний фотоэффект (1888—1890), открыл первый закон фотоэффекта. Исследовал газовый разряд, критическое состояние и другие явления. Основал физическую лабораторию в Императорском Московском университете.
Во́льфганг Па́уль (нем. Wolfgang Paul, МФА: [ˈvɔlfɡaŋ ˈpaʊ̯l]о файле; 10 августа 1913, Лоренцкирх[вд], Саксония — 7 декабря 1993, Бонн, Северный Рейн-Вестфалия) — немецкий физик, профессор, лауреат Нобелевской премии по физике в 1989 году (половина премии совместно с Хансом Демельтом) «за разработку метода удержания одиночных ионов». Вторую половину премии получил Норман Рамзей «за изобретение метода раздельных колебательных полей и его использование в водородном мазере и других атомных часах».
Луис Брюс (англ. Louis E. Brus — Луис Юджин Брус; 10 августа 1943, Кливленд, США — 11 января 2026) — американский физик, специалист по физической химии. Пионер в области квантовых точек. Лауреат Нобелевской премии по химии (2023).
2004 — телескоп Хаббл обнаружил галактику NGC3949, похожую на Млечный путь, и лишился одного из видеосенсоров.
#Biography #Birth_Date #Events #10августа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2