uk
Feedback
Библиотека Java разработчика

Библиотека Java разработчика

Відкрити в Telegram

📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP

Показати більше

📈 Аналітичний огляд Telegram-каналу Библиотека Java разработчика

Канал Библиотека Java разработчика (@bookjava) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 10 278 підписників, посідаючи 12 030 місце в категорії Технології та додатки та 63 913 місце у регіоні Росія.

📊 Показники аудиторії та динаміка

З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 10 278 підписників.

За останніми даними від 05 червня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на 20, а за останні 24 години на 0, загальне охоплення залишається високим.

  • Статус верифікації: Не верифікований
  • Рівень залученості (ER): Середній показник залученості аудиторії становить 8.29%. Протягом перших 24 годин після публікації контент зазвичай збирає 3.77% реакцій від загальної кількості підписників.
  • Охоплення публікацій: В середньому кожен допис отримує 852 переглядів. Протягом першої доби публікація в середньому набирає 388 переглядів.
  • Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 6.
  • Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як string, интерфейс, строка, boot, api.

📝 Опис та контентна політика

Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP

Завдяки високій частоті оновлень (останні дані отримано 07 червня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.

10 278
Підписники
Немає даних24 години
+27 днів
+2030 день
Архів дописів
👩‍💻 Java-разработчик? Хотите ускорить разработку и избавиться от рутины? На открытом уроке «Kotlin Multiplatform: лайфхак д
👩‍💻 Java-разработчик? Хотите ускорить разработку и избавиться от рутины? На открытом уроке «Kotlin Multiplatform: лайфхак для Java-разработчиков» от OTUS мы покажем, как с помощью Kotlin Multiplatform (KMP) использовать один и тот же код для различных проектов — от Android и iOS до backend-систем. Что вас ждёт: ✔️ Узнаете, как интегрировать Kotlin Multiplatform в Java-проекты и настроить совместимость с существующим стеком. ✔️ Сможете избежать дублирования логики и сэкономите время на поддержке разных модулей для разных платформ. ✔️ Получите практические знания, как создавать общий код для JVM, Android и iOS. Открытый урок проходит в преддверии старта курса «Kotlin Backend Developer. Professional». 🎁 Всем участникам вебинара дарим промокод, который дает скидку на обучение - Kotlin5 ➡️ Встречаемся 14 мая в 20:00 МСК — присоединяйтесь и узнайте, как сэкономить время и силы с Kotlin Multiplatform: https://vk.cc/cLEsDR Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

💡 Не делай этого в @PostConstruct — особенно в проде Сейчас расскажу, почему инициализировать важную бизнес-логику в @PostCo
💡 Не делай этого в @PostConstruct — особенно в проде Сейчас расскажу, почему инициализировать важную бизнес-логику в @PostConstruct — плохая идея. Типичный пример:

@Component
public class CacheLoader {

    private final SomeService service;

    public CacheLoader(SomeService service) {
        this.service = service;
    }

    @PostConstruct
    public void init() {
        service.loadDataIntoCache(); // ⚠️ обращение к БД
    }
}
🧨 Проблема: @PostConstruct вызывается до того, как приложение полностью поднялось. Если внутри будет ошибка (например, БД недоступна) — приложение может упасть, или что хуже — запуститься в полурабочем состоянии. 📌 Кроме того: * ❌ Нет контроля над порядком выполнения таких методов; * ❌ Нельзя легко переиспользовать эту логику (например, вручную перезагрузить кеш); * ❌ В тестах или dev-среде — такие вызовы часто мешают. ✅ Современный подход — использовать ApplicationListener:

@Component
public class CacheLoader implements ApplicationListener<ApplicationReadyEvent> {

    private final SomeService service;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        service.loadDataIntoCache(); // 👍 вызывается только после старта
    }
}
📌 Альтернатива — аннотация @EventListener:

@EventListener(ApplicationReadyEvent.class)
public void onReady() {
    // безопасно загружаем данные
}
📦 В Spring Boot это нативный и рекомендованный способ выполнения кода после старта. 🧠 Резюме: 🔹 @PostConstruct — только для простой инициализации бинов. 🔹 Бизнес-логику и I/O — в @EventListener(ApplicationReadyEvent.class). 👉@BookJava

🧠Понимание архитектуры памяти JVM В этой статье мы углубимся в архитектуру памяти JVM (Java Virtual Machine), исследуя, как
🧠Понимание архитектуры памяти JVM В этой статье мы углубимся в архитектуру памяти JVM (Java Virtual Machine), исследуя, как она управляет памятью, чтобы эффективно выполнять Java-программы. 🔹Что такое JVM? JVM — это абстрактная вычислительная машина, которая позволяет запускать Java-программы, независимо от аппаратного или операционного окружения. Она отвечает за интерпретацию байт-кода Java и выполнение его на хост-машине. Архитектура памяти JVM Архитектура памяти JVM делится на несколько компонентов, каждый из которых играет ключевую роль в управлении памятью во время выполнения программы. Основные области памяти JVM: 🔹1. Heap (Куча) * Куча — это основная область памяти, используемая для хранения объектов. * Это самая большая часть памяти и управляется сборщиком мусора (Garbage Collector). * Объекты, созданные во время выполнения программы, размещаются в куче. Куча делится на: * Young Generation (Молодое поколение): * Хранит недавно созданные объекты. * Подразделяется на Eden Space и два Survivor Space (S0 и S1). * Old Generation (Старое поколение): * Хранит долго живущие объекты, которые пережили несколько сборок мусора в молодом поколении. 🔹2. Stack (Стек) * У каждой нити (потока) есть свой собственный стек. * Хранит фреймы методов, включая локальные переменные, операнды и возвращаемые адреса. * Память в стеке освобождается, когда метод завершает выполнение. 🔹3. Method Area (Область методов) * Используется для хранения метаданных классов, таких как: * Информация о типах, * Константы, * Статические переменные, * Методы и их байт-код. * В некоторых реализациях JVM эта область называется Metaspace (начиная с Java 8). 🔹4. Program Counter (PC Register) * Каждая нить имеет собственный регистр PC. * Хранит адрес текущей выполняемой инструкции. 🔹5. Native Method Stack (Стек нативных методов) * Используется для выполнения нативных (не-Java) методов, написанных на других языках, таких как C или C++. Управление памятью и сборка мусора JVM использует автоматическую сборку мусора для управления кучей. Различные алгоритмы (например, Mark and Sweep, Generational GC) используются для отслеживания и удаления неиспользуемых объектов. Это повышает производительность и предотвращает утечки памяти. https://thedeveloperstory.com/2025/04/06/understanding-jvm-memory-architecture/ 👉@BookJava

📊 Данные — это топливо цифрового бизнеса. Однако передача данных между системами по-прежнему требует времени, ресурсов и нер
📊 Данные — это топливо цифрового бизнеса. Однако передача данных между системами по-прежнему требует времени, ресурсов и нервов. Kafka Connect меняет правила игры: минимум кода, максимум автоматизации. 🔄 📅 12 мая в 18:00 МСК на открытом вебинаре от OTUS: — Разберём архитектуру Kafka Connect; — Запустим коннекторы для БД и файловых систем; — Научим масштабировать и отлаживать интеграции; — Покажем, как избежать типовых ошибок. 👤 Спикер: Валентин Шилин — старший программист/аналитик данных в зарубежной компании. Этот вебинар будет полезен разработчикам, инженерам данных, архитекторам и всем, кто работает с интеграциями. 🌐 Открытый урок проходит в преддверии старта курса «Apache Kafka». Все участники получат скидку на обучение. 🔗 Регистрируйтесь прямо сейчас: https://vk.cc/cLEosU Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

🧠 Нюанс с Optional.map() и методами, возвращающими Optional Многие Java-разработчики на автомате пишут что-то вроде: Optiona
🧠 Нюанс с Optional.map() и методами, возвращающими Optional Многие Java-разработчики на автомате пишут что-то вроде:

Optional<User> user = findUserById(id); // возвращает Optional<User>

Optional<String> email = user.map(User::getEmail); // getEmail тоже возвращает Optional<String>
⚠️ Проблема: map() в Optional не "разворачивает" вложенные Optional. В этом примере email будет типа Optional<Optional<String>>, что почти всегда нежелательно. 📌 Правильный способ — использовать flatMap():

Optional<String> email = user.flatMap(User::getEmail);
💡 flatMap() позволяет избежать "двойной обёртки", если метод внутри map() уже возвращает Optional. 🔁 Аналогичная ситуация с Stream.map() — если внутри map() вызывается метод, возвращающий Stream, то получится Stream<Stream<T>>, и опять же нужно использовать flatMap(). 🧪 Мини-памятка: * map() — когда метод возвращает обычный тип (T → R); * flatMap() — когда метод возвращает Optional или Stream (T → Optional<R> или T → Stream<R>). 👉@BookJava

🧠 ExecutorService vs Virtual Threads: подводный камень с shutdownNow() Java 21 принес Virtual Threads (Preview), и всё чаще
🧠 ExecutorService vs Virtual Threads: подводный камень с shutdownNow() Java 21 принес Virtual Threads (Preview), и всё чаще появляется соблазн запускать их через ExecutorService. Но вот что важно помнить: 📌 shutdownNow() — опасная ловушка при работе с виртуальными потоками.

ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

Future<?> future = executor.submit(() -> {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        System.out.println("Interrupted!");
    }
});

executor.shutdownNow(); // ❗️Ничего не произойдёт
💡 Почему? Метод shutdownNow() не может прервать виртуальные потоки, если они запущены через Executors.newVirtualThreadPerTaskExecutor(). Он лишь помечает пул как завершённый и возвращает список задач, которые ещё не стартовали. Уже запущенные виртуальные потоки продолжают выполняться — Thread.interrupt() не работает, потому что у виртуальных потоков отсутствует связь с ThreadGroup, к которому привязан shutdownNow. ⚠️ Следствие: Если вы рассчитываете, что shutdownNow() "остановит всё" — вы можете получить утечку задач или зависания. 🔧 Что делать? 1. Контролируйте завершение через Future.cancel(true) — он вызывает interrupt() на конкретной задаче. 2. Стройте явную кооперативную модель отмены — с флагами или Thread.interrupted() внутри задачи. 3. Для массовой отмены — храните Future задач и отменяйте вручную. 👉@BookJava

🧠 Знаешь ли ты, что @Transactional на private - методах не работает? Да, Spring просто не применяет прокси к private-методам
🧠 Знаешь ли ты, что @Transactional на private - методах не работает? Да, Spring просто не применяет прокси к private-методам. Это частый баг, который трудно отловить: ты вызываешь приватный метод внутри бина, а транзакция… не начинается 🤷‍♂️ 📌 Почему так происходит? Spring AOP по умолчанию использует динамические прокси (JDK или CGLIB), которые перехватывают внешние вызовы. А вызов private - метода из того же класса — это внутренний вызов, который обходит прокси. Пример, который НЕ работает:

@Service
public class UserService {

    public void createUser() {
        saveUser(); // Вызов мимо прокси 😞
    }

    @Transactional
    private void saveUser() {
        // Транзакция НЕ начнется!
    }
}
💡 Как правильно: 1. Сделай метод public или хотя бы protected, 2. Или выноси в отдельный бин:

@Service
public class UserService {

    private final TxUserSaver txUserSaver;

    public UserService(TxUserSaver txUserSaver) {
        this.txUserSaver = txUserSaver;
    }

    public void createUser() {
        txUserSaver.saveUser(); // Теперь через прокси ✅
    }
}

@Service
public class TxUserSaver {

    @Transactional
    public void saveUser() {
        // Всё сработает как надо
    }
}
⚠️ Проверь свои сервисы — ты можешь удивиться, сколько транзакций у тебя не работают. Особенно в проектах, где @Transactional ставят "на всякий случай". 👉@BookJava

⚡️ Квиз на знание Java Пройти тестирование — сложно! А ты справишься? 21 вопрос, 30 минут Проверь себя - пройди квиз и оцени
⚡️ Квиз на знание Java Пройти тестирование — сложно! А ты справишься? 21 вопрос, 30 минут Проверь себя - пройди квиз и оцени свой уровень навыков, а также свою готовность к обучению на курсе — «Разработчик на Spring Framework» от OTUS. 💻 За 5 месяцев обучения ты освоишь современные возможности Spring, научишься быстро проходить путь от идеи до production-grade, создавать Web-приложения на микросервисной архитектуре и решать высокоуровневые задачи по разработке. 👉 ПРОЙТИ ТЕСТ: https://vk.cc/cLshxc Если успешно пройдешь тест, сможешь забронировать место в группе по выгодной цене! И еще дарим промокод SPRING5 Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

+7
Java. Сортировки Java. Сортировка пузырьком. Java. О сортировке выбором. Java. Быстрая сортировка. Объяснение на пальцах) Java. Оценка сложности алгоритмов сортировки. Java. Сортировка слиянием. Java. Сортировка подсчетом. Java. Сортировка вставками. Java. Сортировка расческой. От пузырька до расчески. 👉@BookJava

🧠 Как в Java сломать equals() и потерять данные в HashMap Сегодня покажу, как неочевидный баг в equals()/hashCode() может пр
🧠 Как в Java сломать equals() и потерять данные в HashMap Сегодня покажу, как неочевидный баг в equals()/hashCode() может привести к потере данных при работе с HashMap. Допустим, у вас есть Entity:

public class User {
    private String id;
    private String name;

    // equals/hashCode только по id
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return Objects.equals(id, user.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
Вроде норм. Но теперь добавим такого юзера в HashMap, а потом... изменим его id:

User user = new User();
user.setId("1");
user.setName("Alice");

Map<User, String> map = new HashMap<>();
map.put(user, "value");

user.setId("2"); // ⚠️ ключ стал "невидимым"

System.out.println(map.get(user)); // null 😱
📌 Почему так происходит? HashMap ищет ключ по hashCode() → ищет бакет → сравнивает через equals(). А hashCode() уже другой, и объект "теряется". 💡 Совет: если вы используете объект как ключ в мапе или добавляете его в Set, не изменяйте его поля, участвующие в equals()/hashCode()! 📌 А как правильно? - Делайте такие поля final; - Или используйте неизменяемые типы (record); - Или не используйте такие объекты как ключи вовсе. Вот безопасный вариант с record:

public record User(String id, String name) {}
👉@BookJava

🤖 А ты справишься с тестом по Kotlin? 🏆 Пройди тест из 10 вопросов, проверь свой уровень знаний и получи скидку на онлайн-к
🤖 А ты справишься с тестом по Kotlin? 🏆 Пройди тест из 10 вопросов, проверь свой уровень знаний и получи скидку на онлайн-курс «Kotlin Backend Developer. Professional» от OTUS! Если успешно пройдешь тест, сможешь забронировать место в группе по выгодной цене! И еще дарим промокод Kotlin5 🎫 Курс можно приобрести в рассрочку ➡️ Пройти тест и забрать скидку: https://vk.cc/cLkRLn Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

💡Сегодня покажу крутую фишку для оптимизации чтения больших коллекций из базы через JPA. 📌 Проблема: Когда загружаем большу
💡Сегодня покажу крутую фишку для оптимизации чтения больших коллекций из базы через JPA. 📌 Проблема: Когда загружаем большую коллекцию через @OneToMany, Hibernate часто делает это лениво (LAZY), но при первом доступе — забирает всю коллекцию целиком. Это может привести к OutOfMemoryError или резкому проседанию производительности. 📌 Решение: использовать пагинацию (batch-size) или запрос коллекции порциями. Как настроить batch-size на уровне сущности:

@Entity
public class User {
    
    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
    @BatchSize(size = 50)
    private List<Order> orders;
}
🧠 Теперь Hibernate будет загружать за раз по 50 элементов, а не всю коллекцию сразу! 📌 Или можно настроить глобально через application.properties:

spring.jpa.properties.hibernate.default_batch_fetch_size=50
⚠️ Важно: - @BatchSize работает только для LAZY-связей. - Это не пагинация в SQL, а оптимизация внутренних запросов Hibernate. - Если коллекция огромная (100k+ записей) — лучше делать явные paged запросы в репозитории. 💡Помните: без настройки batch-size Hibernate может сломать приложение под нагрузкой. Оптимизируйте загрузку коллекций заранее! 👉@BookJava

1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟 Как меняется ИТ-индустрия с внедрением AI? Узнай 6 июня на ИТ-конференции МТС True Tech Day Tru
1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟 Как меняется ИТ-индустрия с внедрением AI? Узнай 6 июня на ИТ-конференции МТС True Tech Day True Tech Day 2025 — третья масштабная технологическая конференция МТС для профессионалов ИТ‑индустрии. В программе: — Больше 40 докладов от известных ученых и ИТ-компаний. — Выступления зарубежных спикеров с индексом Хирша более 50. — Концентрация практических кейсов: как создаются большие проекты с применением AI. — Доклады по архитектуре, бэкенд-разработке и построению ИТ-платформ. — AI-интерактивы и технологические квесты. — Пространство для нетворкинга, …а еще after-party со звездным лайн-апом. Когда: 6 июня Где: Москва, МТС Live Холл и онлайн Участие бесплатно.Регистрация по ссылке.

Как работают instance initializer blocks. Пример с родительским и дочерним классами:

class Parent {
    int a = 5;

    {
        System.out.println("Parent instance initializer");
        a = 10;
    }

    Parent() {
        System.out.println("Parent constructor, a = " + a);
    }
}

class Child extends Parent {
    int b = 15;

    {
        System.out.println("Child instance initializer");
        b = 25;
    }

    Child() {
        System.out.println("Child constructor, b = " + b);
    }
}

public class Test {
    public static void main(String[] args) {
        Child child = new Child();
    }
}
Вывод программы:
Parent instance initializer
Parent constructor, a = 10
Child instance initializer
Child constructor, b = 25
Пошаговое выполнение: 1. Сначала загружается родительский класс Parent. 2. Выполняется: - Инициализация полей родителя (a = 5), - Потом instance initializer блока родителя (a = 10), - Потом конструктор родителя (Parent()). 3. Далее переходим к дочернему классу Child: - Инициализация полей дочернего класса (b = 15), - Потом instance initializer блока дочернего класса (b = 25), - Потом конструктор дочернего класса (Child()). Важный порядок действий: 1. Инициализация родителя → 2. Конструктор родителя → 3. Инициализация потомка → 4. Конструктор потомка. Блоки инициализации всегда выполняются до тела конструктора, но после вызова super(). 👉@BookJava

В Java instance initializer blocks (блоки инициализации экземпляра) выполняются в следующем порядке: - Они выполняются каждый раз, когда создается новый объект класса. - Выполнение происходит после вызова конструктора родительского класса (super()), но до тела конструктора текущего класса. Порядок инициализации: 1. Сначала инициализируются поля в порядке их объявления. 2. Затем выполняются instance initializer blocks, в том порядке, в котором они написаны в коде. 3. После этого выполняется тело конструктора. Пример:

class Example {
    int x = 10;

    {
        System.out.println("Instance initializer block");
        x = 20;
    }

    Example() {
        System.out.println("Constructor");
        System.out.println("x = " + x);
    }

    public static void main(String[] args) {
        Example ex = new Example();
    }
}
Вывод:
Instance initializer block
Constructor
x = 20
Ключевые моменты: - Статические блоки (static {}) — другое дело: они выполняются один раз при загрузке класса. - Instance initializer blocks полезны для общей инициализации, которую нужно выполнять вне зависимости от того, какой конструктор вызывается. 👉@BookJava

Есть фича. Есть дедлайн. Есть понимание, что тесты надо писать… но они отъедают время, которого итак впритык. Один наш знаком
Есть фича. Есть дедлайн. Есть понимание, что тесты надо писать… но они отъедают время, которого итак впритык. Один наш знакомый девелопер сказал: «С тех пор как поставил Explyt Test — начал писать меньше тестов… но покрытие стало лучше. Как это вообще возможно?!» Попробуйте сами. Плагин сам предлагает тесты для вашего кода — прямо в IDE. 👉 explyt.ai — сэкономь себе пару часов уже сегодня.

🧠 Сегодня покажу вам полезный трюк для Spring Boot: как элегантно валидировать параметры контроллера без лишнего кода. Часто
🧠 Сегодня покажу вам полезный трюк для Spring Boot: как элегантно валидировать параметры контроллера без лишнего кода. Часто вижу, как в контроллерах вручную проверяют @RequestParam на пустоту или формат. Это шумит код и приводит к ошибкам. Вместо этого используйте аннотации валидации прямо на параметрах:

@RestController
@RequestMapping("/api")
@Validated // Обязательно!
public class UserController {

    @GetMapping("/users")
    public List<User> getUsers(
            @RequestParam @NotBlank String name,
            @RequestParam @Min(18) int age
    ) {
        // Если валидация не пройдена — автоматически вернётся 400 Bad Request
        return userService.findUsers(name, age);
    }
}
📌 Ключевые моменты: - Обязательно ставим @Validated над классом контроллера. - На параметры добавляем любые стандартные аннотации из jakarta.validation.constraints. - Ошибки валидации Spring обработает автоматически через MethodArgumentNotValidException. 💡 Можно кастомизировать ответ на ошибку, добавив глобальный @ExceptionHandler. ⚠️ Без @Validated аннотации на контроллере валидация параметров работать не будет! 👉@BookJava

📌 Ошибка: Вызов метода с @Transactional внутри того же класса не запускает новую транзакцию. Почему? Spring оборачивает бин
📌 Ошибка: Вызов метода с @Transactional внутри того же класса не запускает новую транзакцию. Почему? Spring оборачивает бин в прокси, а внутренние вызовы проходят мимо прокси, значит, аннотация игнорируется. Пример проблемы:

@Service
public class OrderService {

    @Transactional
    public void createOrder() {
        saveOrder();
    }

    @Transactional
    public void saveOrder() {
        // Новый транзакционный контекст не создастся!
    }
}
💡 Как правильно: 1. Вынести saveOrder() в отдельный бин. 2. Или получить прокси текущего бина через AopContext:

@Service
@EnableAspectJAutoProxy(exposeProxy = true) // важно!
public class OrderService {

    @Transactional
    public void createOrder() {
        ((OrderService) AopContext.currentProxy()).saveOrder();
    }

    @Transactional
    public void saveOrder() {
        // Теперь всё ок ✅
    }
}
⚠️ Важный момент: exposeProxy = true нужен на уровне конфигурации, иначе AopContext не заработает. Понимание этой тонкости критично для корректного управления транзакциями в Spring! 🚀 👉@BookJava

🚀 Подборка Telegram каналов для программистов Системное администрирование, DevOps 📌 https://t.me/bash_srv Bash Советы https://t.me/win_sysadmin Системный Администратор Windows https://t.me/sysadmin_girl Девочка Сисадмин https://t.me/srv_admin_linux Админские угодья https://t.me/linux_srv Типичный Сисадмин https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin https://t.me/linux_odmin Linux: Системный администратор https://t.me/devops_star DevOps Star (Звезда Девопса) https://t.me/i_linux Системный администратор https://t.me/linuxchmod Linux https://t.me/sys_adminos Системный Администратор https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало) https://t.me/sysadminof Книги для админов, полезные материалы https://t.me/i_odmin Все для системного администратора https://t.me/i_odmin_book Библиотека Системного Администратора https://t.me/i_odmin_chat Чат системных администраторов https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др. https://t.me/sysadminoff Новости Линукс Linux 1C разработка 📌 https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С https://t.me/DevLab1C 1С:Предприятие 8 https://t.me/razrab_1C 1C Разработчик https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт https://t.me/rabota1C_rus Вакансии для программистов 1С Программирование C++📌 https://t.me/cpp_lib Библиотека C/C++ разработчика https://t.me/cpp_knigi Книги для программистов C/C++ https://t.me/cpp_geek Учим C/C++ на примерах Программирование Python 📌 https://t.me/pythonofff Python академия. https://t.me/BookPython Библиотека Python разработчика https://t.me/python_real Python подборки на русском и английском https://t.me/python_360 Книги по Python Java разработка 📌 https://t.me/BookJava Библиотека Java разработчика https://t.me/java_360 Книги по Java Rus https://t.me/java_geek Учим Java на примерах GitHub Сообщество 📌 https://t.me/Githublib Интересное из GitHub Базы данных (Data Base) 📌 https://t.me/database_info Все про базы данных Мобильная разработка: iOS, Android 📌 https://t.me/developer_mobila Мобильная разработка https://t.me/kotlin_lib Подборки полезного материала по Kotlin Фронтенд разработка 📌 https://t.me/frontend_1 Подборки для frontend разработчиков https://t.me/frontend_sovet Frontend советы, примеры и практика! https://t.me/React_lib Подборки по React js и все что с ним связано Разработка игр 📌 https://t.me/game_devv Все о разработке игр Библиотеки 📌 https://t.me/book_for_dev Книги для программистов Rus https://t.me/programmist_of Книги по программированию https://t.me/proglb Библиотека программиста https://t.me/bfbook Книги для программистов БигДата, машинное обучение 📌 https://t.me/bigdata_1 Big Data, Machine Learning Программирование 📌 https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций https://t.me/rust_lib Полезный контент по программированию на Rust https://t.me/golang_lib Библиотека Go (Golang) разработчика https://t.me/itmozg Программисты, дизайнеры, новости из мира IT https://t.me/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 https://t.me/nodejs_lib Подборки по Node js и все что с ним связано https://t.me/ruby_lib Библиотека Ruby программиста https://t.me/lifeproger Жизнь программиста. Авторский канал. QA, тестирование 📌 https://t.me/testlab_qa Библиотека тестировщика Шутки программистов 📌 https://t.me/itumor Шутки программистов Защита, взлом, безопасность 📌 https://t.me/thehaking Канал о кибербезопасности https://t.me/xakep_2 Хакер Free Книги, статьи для дизайнеров 📌 https://t.me/ux_web Статьи, книги для дизайнеров Математика 📌 https://t.me/Pomatematike Канал по математике https://t.me/phis_mat Обучающие видео, книги по Физике и Математике https://t.me/matgeoru Математика | Геометрия | Логика Excel лайфхак📌 https://t.me/Excel_lifehack https://t.me/mir_teh Мир технологий (Technology World) Вакансии 📌 https://t.me/sysadmin_rabota Системный Администратор https://t.me/progjob Вакансии в IT

Сегодня покажу вам 🧠 один тонкий момент в работе с Optional, который часто ловит даже опытных. Многие пишут так: Optional op
Сегодня покажу вам 🧠 один тонкий момент в работе с Optional, который часто ловит даже опытных. Многие пишут так:

Optional<String> optional = getValue();
if (optional.isPresent()) {
    doSomething(optional.get());
}
⚠️ Это антипаттерн! Вы теряете суть Optional и рискуете ошибками в многопоточке. 📌 Правильный способ — использовать функциональный стиль:

getValue().ifPresent(this::doSomething);
Или ещё элегантнее:

getValue()
    .map(this::transform)
    .filter(this::isValid)
    .ifPresent(this::doSomething);
💡 Подходы: - map для преобразования значения - filter для отсеивания ненужных - orElse, orElseGet, orElseThrow для обработки отсутствия - ifPresentOrElse в Java 9+ для двух вариантов действий 📈 Выгоды: - Код становится компактнее - Безопаснее при рефакторинге - Лучше для чтения в потоковых операциях (Stream API) 🛠 Если нужно вынуть значение — используйте orElseThrow() вместо .get():

String value = getValue().orElseThrow(() -> new IllegalStateException("Value not found"));
👉 Отказывайтесь от .isPresent() и .get() связки — используйте силу функционального подхода! 🚀 👉@BookJava