Библиотека Java разработчика
10.8K subscribers
1.14K photos
564 videos
58 files
1.44K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
Подборка Telegram каналов для программистов

https://t.me/lifeproger Жизнь программиста. Авторский канал.
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://t.me/rabota1C_rus 1С Работа

Системное администрирование 📌
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин

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С

Программирование 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 академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus

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/books_reserv Книги для программистов

БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning

Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию
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 программиста

QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика

Шутки программистов 📌
https://t.me/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_1 Статьи из "Хакера"

Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров

Английский 📌
https://t.me/UchuEnglish Английский с нуля

Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике

Excel лайфхак📌
https://t.me/Excel_lifehack

https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)

Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
👍3
Stream API: Обзор и Основные Методы

Stream API – мощный инструмент для обработки данных. Его основные принципы:
Композиция – построение логики из небольших, независимых и чистых функций.
Single Responsibility – каждый шаг выполняет одну конкретную операцию.

Такой подход обеспечивает:
✔️ Читаемость кода.
✔️ Отсутствие локальных переменных.
✔️ Линейную последовательность действий.

Основные компоненты Stream API
Любой поток состоит из трех ключевых частей:
1️⃣ Источник данных (коллекция, массив, файл и т. д.).
2️⃣ Промежуточные преобразования (filter, map и другие).
3️⃣ Конечная операция (коллекционирование, агрегация, перебор).

Способы создания стрима
Stream можно создать несколькими способами:

🔹 Из коллекции: collection.stream()
🔹 Из массива: Arrays.stream(array)
🔹 Из набора элементов: Stream.of(1, 2, 3)
🔹 Бесконечный поток: Stream.iterate(0, n -> n + 1)
🔹 Бесконечный поток с ограничением (Java 9): Stream.iterate(1, n -> n < 100, n -> n * 2)
🔹 Генерация элементов: Stream.generate(Math::random)
🔹 Диапазон значений:
- IntStream.range(1, 5) (1, 2, 3, 4)
- IntStream.rangeClosed(1, 5) (1, 2, 3, 4, 5)
🔹 Из файла: Files.lines(Path.of("file.txt"))
🔹 Из строки: "abc".chars()

Промежуточные операции
Stream API поддерживает множество преобразований. Наиболее распространенные:

✔️ Фильтрация: filter(Predicate<T>) – оставляет только элементы, соответствующие условию.
✔️ Удаление дубликатов: distinct() – исключает повторяющиеся элементы.
✔️ Ограничение количества: limit(n) – берет первые n элементов.
✔️ Сортировка: sorted() – упорядочивает элементы.

Менее очевидные операции
🔹 map(Function<T, R>) – применяет функцию к каждому элементу.
🔹 flatMap(Function<T, Stream<R>>) – «разворачивает» элементы из вложенных структур.
🔹 takeWhile(Predicate<T>) (Java 9) – берет элементы, пока выполняется условие.
🔹 dropWhile(Predicate<T>) (Java 9) – пропускает элементы, пока условие выполняется.
🔹 peek(Consumer<T>) – выполняет действие без изменения элементов (удобно для логирования).

Конечные операции
Стрим начинает обработку данных только при вызове конечной операции:

📌 Коллекционирование:
- collect(Collectors.toList()) – собирает в List.
- collect(Collectors.toSet()) – собирает в Set.

📌 Поиск элементов:
- findFirst() – первый элемент.
- findAny() – любой элемент (оптимизирован для параллельных потоков).
- anyMatch(Predicate<T>) – хотя бы один элемент удовлетворяет условию.
- allMatch(Predicate<T>) – все элементы удовлетворяют условию.
- noneMatch(Predicate<T>) – ни один элемент не удовлетворяет условию.

📌 Агрегация:
- min(Comparator<T>) – минимальный элемент.
- max(Comparator<T>) – максимальный элемент.
- count() – количество элементов.
- reduce(BinaryOperator<T>) – свертка элементов в одно значение.

📌 Побочные эффекты:
- forEach(Consumer<T>) – выполняет действие над каждым элементом.
- forEachOrdered(Consumer<T>) – выполняет действие, сохраняя порядок (важно для параллельных потоков).

Особенности работы со Stream API
1️⃣ Стрим – это не структура данных
Он лишь обходит источник, выполняя операции лениво.

2️⃣ Стрим нельзя использовать повторно
После вызова конечной операции повторное использование потока приведет к IllegalStateException.

3️⃣ Исходные данные не изменяются
Методы Stream API не модифицируют исходную коллекцию.

Разбор сложных случаев
Ошибочный код:

Stream.of(-1, 0, 1).max(Math::max).get();

Почему ошибка?
Метод max() принимает Comparator<T>, но Math.max(a, b) – это BiFunction<Integer, Integer, Integer>. Они не эквивалентны!

ℹ️ Решение:

Stream.of(-1, 0, 1).max(Integer::compareTo).get(); // Вернет 1


👉@BookJava
👍103🎉3🔥1🤨1
📝 Советы по оптимизации Java кода: избавляемся от лишнего

Привет, друзья! Сегодня поговорим об оптимизации кода. Все мы знаем, что код должен быть не только работоспособным, но и читаемым, эффективным и поддерживаемым. Давайте разберем несколько типичных ошибок и способов их устранения.

🚀 1. Избегайте ненужного создания объектов
Частая ошибка — создавать объекты там, где можно использовать уже существующие.

Плохо:

String str = new String("Hello"); // Избыточно

Хорошо:

String str = "Hello"; // Используем строковый пул

То же самое касается Integer.valueOf() вместо new Integer().

🔄 2. Используйте StringBuilder вместо конкатенации в цикле
Если вы объединяете строки в цикле, StringBuilder будет значительно быстрее.

Плохо:

String result = "";
for (int i = 0; i < 100; i++) {
result += i; // Создает новый объект String на каждой итерации
}

Хорошо:

StringBuilder result = new StringBuilder();
for (int i = 0; i < 100; i++) {
result.append(i);
}

Такой код работает в разы быстрее!

🏎 3. Правильно выбирайте коллекции
Используйте ArrayList, если не нужна частая вставка/удаление элементов в середине списка.
Используйте HashSet, если важны уникальные значения и не нужен порядок.
Используйте LinkedList, если нужна частая вставка/удаление в середине списка.

4. Не злоупотребляйте Stream API
Да, Stream API удобен, но иногда он замедляет код. Например:

Плохо:

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, Integer::sum);

Хорошо:

int sum = 0;
for (int num : numbers) {
sum += num;
}

Цикл быстрее, потому что не тратит время на создание объектов и лямбды.

🔥 Вывод
Оптимизация — это не просто ускорение кода, но и улучшение его читаемости и поддержки. Используйте правильные структуры данных, избегайте лишних аллокаций, выбирайте оптимальные конструкции.

А какие советы по оптимизации Java кода используете вы? Пишите в комментариях! 👇 🚀

👉@BookJava
👍14
Бесплатный вебинар, который поможет начать изучение Spark с нуля!

👨‍💻🛠👨🏻‍💻 Кому будет полезно?
- Data-инженерам и аналитикам, работающим с большими объемами данных
- Программистам, переходящим с других технологий обработки данных на Spark

Не пропустите прямой эфир, где мы начнем изучение Big Data фреймворка и подробно разберем обработку графов с помощью Spark:
- ключевые понятия, включая структуру графов, а также алгоритмы, доступные в библиотеках GraphX и GraphFrames
- создание и обработку графов на основе различных типов данных
- эффективную работу с большими графами
- 2 популярных алгоритма для анализа данных: PageRank и Connected Components
- интеграцию графов в проекты
- практические примеры построения графов и их анализ

Все участники вебинара смогут продолжить обучение на курсе «Spark Developer» с выгодной скидкой.

➡️ Регистрация: https://vk.cc/cIVWCl

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
👍1
📝 Разбираем @Transactional в Spring: Где Подводные Камни?

Давайте обсудимм одну из самых популярных аннотаций в Spring — @Transactional. Многие знают, что она используется для управления транзакциями, но не все понимают, как она работает под капотом и какие проблемы могут возникнуть. Давайте разбираться!

🔍 Как работает @Transactional?
Когда вы помечаете метод @Transactional, Spring проксирует этот метод и оборачивает его в транзакцию. Это значит, что до начала метода открывается транзакция, а после — либо коммитится (если нет ошибок), либо откатывается (если есть исключение).

Но тут важно помнить:
🔹 @Transactional работает только на public методах (если используется Spring AOP).
🔹 Вызовы методов внутри одного класса не учитывают @Transactional. Если вызвать метод, аннотированный @Transactional, внутри другого метода того же класса, транзакция не создастся.
🔹 По умолчанию, транзакция откатывается только при RuntimeException. Если бросить checked-исключение, Spring не откатит транзакцию.

⚠️ Распространённые ошибки
Аннотация на private методе
Транзакция просто не будет работать, так как Spring AOP не перехватит вызов.

Вызов @Transactional метода внутри того же класса
Транзакция не создастся, так как вызов происходит без участия Spring Proxy. Решение — выносить такие методы в отдельный бин или использовать TransactionTemplate.

Неправильный rollback
Если в методе выбрасывается checked-исключение, Spring по умолчанию **не откатывает** транзакцию. Чтобы изменить это поведение, нужно явно указать `@Transactional(rollbackFor = Exception.class).

Как избежать проблем?
✔️ Всегда ставьте @Transactional на публичные методы.
✔️ Вызывайте @Transactional-методы только через Spring-управляемые бины.
✔️ Контролируйте rollback через rollbackFor.
✔️ Используйте propagation = REQUIRES_NEW, если хотите создать новую независимую транзакцию.

Кто сталкивался с неожиданным поведением @Transactional? Давайте обсудим в комментариях!

👉 @BookJava
👍13
🚀 AutoCloseable HttpClient в Java 21 🚀

HttpClient был обновлён и теперь реализует интерфейс AutoCloseable в Java 21. 🔥

👉 @BookJava
👍7
⚡️👩‍💻 Освой Java с нуля и начни карьеру успешного разработчика!

Мечтаешь вкатиться в IT, но думаешь, что уже поздно? Java — язык, на котором работают крупнейшие компании мира! Тебе точно найдется место.

🦾 Наше обучение на курсе "Java-разработчик" — это 3 ступени, которые проведут тебя от новичка до уверенного Middle-разработчика. Ты освоишь Spring, Hibernate, PostgreSQL, Docker, Kafka, Kubernetes и другие актуальные технологии!

Программа составлена практикующими экспертами, а диплом OTUS востребован в ведущих IT-компаниях. Наш партнер — СберКорус, разработчик передовых цифровых решений!

👉 Оставь заявку и получи скидку на курс: https://vk.cc/cIVZFZ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
Абстракция в Java – что это и зачем нужна?

Одна из ключевых концепций ООП – абстракция. Мы постоянно используем её в Java, даже не задумываясь. Но давайте разберёмся, зачем она нужна и как правильно применять.

📌 Что такое абстракция?
Абстракция – это процесс выделения существенных характеристик объекта, скрывая при этом детали реализации. Это позволяет нам работать с объектами через их интерфейсы, а не конкретные реализации.

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

🔹 Как реализуется абстракция в Java?
В Java абстракция достигается двумя способами:
1. Абстрактные классы (abstract class)
2. Интерфейсы (interface)

🚀 Абстрактные классы
Абстрактный класс может содержать как реализованные, так и абстрактные (без реализации) методы. Его нельзя создать через new, он служит основой для дочерних классов.


abstract class Vehicle {
abstract void start(); // абстрактный метод, без реализации

void stop() {
System.out.println("Машина остановилась");
}
}

class Car extends Vehicle {
@Override
void start() {
System.out.println("Запуск двигателя...");
}
}

public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.start();
car.stop();
}
}

💡 Тут start() – это абстрактный метод, его реализация будет в Car. А вот stop() реализован в базовом классе.

🚀 Интерфейсы
Интерфейсы содержат только сигнатуры методов (до Java 8), а с Java 8 можно добавлять default и static методы.


interface Engine {
void start();
}

class ElectricCar implements Engine {
@Override
public void start() {
System.out.println("Электродвигатель включен!");
}
}

📌 Разница между интерфейсом и абстрактным классом в том, что интерфейсы описывают, что класс ДОЛЖЕН делать, а абстрактные классы – как он МОЖЕТ это делать.

🎯 Где применять абстракцию?
- Если у вас иерархия классов с общими методами – используйте абстрактный класс.
- Если вам нужно гибкое поведение без наследования – используйте интерфейсы.

👉 Абстракция позволяет писать гибкий, расширяемый и поддерживаемый код, уменьшая зависимость от конкретных реализаций.

Как вы чаще применяете абстракцию: через абстрактные классы или интерфейсы? Делитесь опытом в комментариях! 👇

👉@BookJava
👍5🤨1
🚀 Параметры JVM: Какие ключевые стоит знать?

Сегодня я покажу вам самые важные параметры JVM, которые помогут вам оптимизировать работу вашего Java-приложения. Эти флаги влияют на производительность, управление памятью и отладку.

🔥 Управление памятью:
- -Xms<size> – задает начальный размер кучи.
- -Xmx<size> – задает максимальный размер кучи.
- -XX:NewRatio=<n> – определяет соотношение между молодым и старым поколением.
- -XX:SurvivorRatio=<n> – соотношение между Eden и Survivor.

Гаражная сборка (GC):
- -XX:+UseG1GC – включает G1 Garbage Collector (по умолчанию в Java 9+).
- -XX:+UseParallelGC – включает Parallel GC.
- -XX:+UseZGC – включает экспериментальный ZGC (минимальная пауза).
- -XX:+UseShenandoahGC – еще один GC с низкими задержками.

🛠️ Диагностика и отладка:
- -XX:+PrintGCDetails – подробный вывод информации о сборке мусора.
- -XX:+HeapDumpOnOutOfMemoryError – дамп памяти при OOM.
- -XX:HeapDumpPath=<path> – указывает путь для дампа памяти.
- -XX:+ExitOnOutOfMemoryError – завершает JVM при OOM.

🏎️ Оптимизация JIT:
- -XX:+TieredCompilation – адаптивная компиляция кода.
- -XX:+UseStringDeduplication – уменьшает использование памяти строками.
- -XX:+AlwaysPreTouch – аллокация памяти заранее (полезно для больших heap'ов).

Попробуйте поэкспериментировать с этими параметрами и посмотрите, как они влияют на производительность вашего приложения!

Какие параметры JVM используете вы? Пишите в комментариях!

👉 @BookJava
👍8
💥 Apache Kafka: мощь, которой вы еще не владеете! Курс, который сделает вас профи в потоках данных.💥

Превратите свои проекты в образец стабильности и скорости! Учитесь у экспертов, которые знают Kafka изнутри.

На курсе вы научитесь:
- Разворачивать Kafka и настраивать брокеры.
- Использовать API и разрабатывать программы на Kafka Streams, Spring, Akka, ZIO.
- Интегрировать Kafka с другими системами.
- Настроить мониторинг и безопасность.

💼 Реальная практика, живые лекции и диплом, который ценят ведущие компании.

💪 Готовы прокачаться? Пройдите полное тестирование и присоединяйтесь к группе с максимальной скидкой по промокоду "Kafka_5", а также получите доступ к открытым урокам курса: 👉 https://vk.cc/cIX01X

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
👩‍💻 Вы — Java-разработчик, готовый к большему?

Повышение квалификации на курсе «Java Developer. Professional» — это путь от уверенного программиста до востребованного Middle+ специалиста.

Почему этот курс для вас?

— 96 часов практики и детального кода.
— Основы JVM: разберём byteCode и сборку мусора.
— Современные фреймворки: Spring WebFlux, Kafka, Kubernetes.
— Реальные задачи и код-ревью от экспертов.

Преподаватели с опытом в крупнейших компаниях помогут вам:

— Освоить многопоточность и реактивный Postgres.
— Решать задачи уровня Middle+ с уверенностью.
— Писать код быстрее, чище и без лишних багов.

🔥 До 28.02 скидка на все курсы 10%, кроме этого дарим промокод Javapro-02 который прибавляет к скидке еще 5% !!!

🎫 Курс можно приобрести в рассрочку

➡️ Последний шанс пройти тестирование и получить скидку! Не упустите возможность прокачать свои навыки и построить впечатляющую карьеру: https://vk.cc/cIX0s5

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🧵 Разбираемся с CompletableFuture в Java

Сегодня я хочу рассказать вам про CompletableFuture — мощный инструмент для работы с асинхронными операциями в Java. Если вам приходилось ждать выполнения долгих задач в коде и хотелось бы улучшить производительность, то этот пост для вас! 🚀

🔹 Что такое CompletableFuture?
CompletableFuture — это часть java.util.concurrent с Java 8, которая позволяет выполнять асинхронные задачи и удобно комбинировать их. В отличие от обычного Future, CompletableFuture поддерживает цепочки вызовов, композицию задач и обработку ошибок.

🔹 Пример использования
Допустим, у нас есть сервис, который загружает данные по сети. Обычный подход синхронного вызова будет блокировать поток, но с CompletableFuture мы можем избежать этого:


import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
System.out.println("Загружаем данные...");
sleep(2000);
return "Данные загружены";
}).thenApply(data -> {
System.out.println("Обрабатываем: " + data);
return data.toUpperCase();
}).thenAccept(System.out::println)
.exceptionally(ex -> {
System.out.println("Ошибка: " + ex.getMessage());
return null;
});

sleep(3000); // Даем время асинхронной операции завершиться
}

private static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


🔹 Разбор кода
1️⃣ supplyAsync() — запускает асинхронную задачу в отдельном потоке.
2️⃣ thenApply() — позволяет обработать результат (например, изменить его формат).
3️⃣ thenAccept() — принимает готовый результат и выполняет действие.
4️⃣ exceptionally() — обрабатывает возможные ошибки.

🔹 Зачем это нужно?
Улучшает производительность за счет асинхронного выполнения.
Избегает блокировки основного потока.
Позволяет легко комбинировать операции.

Используете ли вы CompletableFuture в своих проектах? Делитесь опытом в комментариях! 👇

👉@BookJava
👍61
⚡️ Квиз на знание Java

Пройти тестирование — сложно! А ты справишься?
22 вопроса, 30 минут

Проверь себя - пройди квиз и оцени свой уровень навыков, а также свою готовность к обучению на курсе — «Java Developer. Advanced» от Отус.

👩‍💻 На курсе ты научишься профилировать приложения, настраивать GC, работать с реактивными подходами и мониторить метрики в Grafana. Пройдешь весь путь от JVM до Kubernetes, научишься анализировать «горячие точки», оптимизировать приложения и настраивать интеграции с Prometheus.

➡️ ПРОЙТИ ТЕСТ: https://vk.cc/cIZDax

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Дикая Java

«Безопасный язык» говорили они, «четкая спецификация» говорили они, «Java не даст вам выстрелить себе в ногу» и прочее в таком духе. Реальность же оказалась куда веселее официальной документации и мнений экспертов.

«JVM темна и полна ужасов». (ц)

https://habr.com/ru/articles/886080/

👉@BookJava
👍4
🚀 Используем Optional правильно в Java

Сегодня разберем Optional – мощный инструмент, который помогает избежать NullPointerException. Но многие используют его неправильно! Давайте посмотрим, как его применять эффективно.

Как делать НЕ надо:

Optional<String> optional = Optional.ofNullable(getValue());
if (optional.isPresent()) {
System.out.println(optional.get());
}

Почему плохо?
- get() без проверки – потенциальная ловушка.
- Лишний if – можно сделать проще.

Как надо:

Optional.ofNullable(getValue()).ifPresent(System.out::println);

или, если нужно значение по умолчанию:

String value = Optional.ofNullable(getValue()).orElse("Default Value");

Крутые приемы с Optional:
orElseGet – лениво вычисляет значение
orElseThrow – выбрасывает исключение, если Optional пуст
map и flatMap – позволяют трансформировать данные

🔥 Советы:
1️⃣ Не используйте Optional для полей классов – это не сериализуемо.
2️⃣ Не передавайте Optional в аргументах методов – это антипаттерн.
3️⃣ Optional хорош для возвращаемых значений – используйте его вместо null.

Как вы используете Optional в своих проектах? Делитесь в комментариях!

👉@BookJava
👍5
🦾👩‍💻Хардкорный тест по языку Java👩‍💻🦾

👩‍💻 Пройдите тест из 21 вопроса и проверьте, насколько вы готовы к обучению на углубленном курсе «Разработчик на Spring Framework» от OTUS.
Сможете сдать - пройдете на курс по спеццене!

💻 За 5 месяцев обучения вы освоите современные возможности Spring, научитесь быстро проходить путь от идеи до production-grade, создавать Web-приложения на микросервисной архитектуре и решать высокоуровневые задачи по разработке.

Время прохождения теста ограничено 30 минут

👉 ПРОЙТИ ТЕСТ: https://vk.cc/cJ4GlS

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
Используем Lombok правильно: Разбираемся с @Slf4j

Сегодня я расскажу вам о @Slf4j из библиотеки Lombok и о том, как его правильно использовать, чтобы ваш код стал чище и удобнее.

Что такое @Slf4j?
Это аннотация, которая добавляет в ваш класс статическое поле логгера org.slf4j.Logger. Вместо того чтобы писать:


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyService {
private static final Logger log = LoggerFactory.getLogger(MyService.class);
}


Достаточно одной аннотации:


import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyService {
}


Теперь в коде можно просто писать:


log.info("Приложение запущено");
log.error("Произошла ошибка: {}", exception.getMessage());


На что обратить внимание?
1️⃣ @Slf4j использует SLF4J API, поэтому вам все равно потребуется подключить реализацию логирования, например Logback:


<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>


2️⃣ Если нужен другой логгер, можно использовать альтернативные аннотации:
- @Log — для java.util.logging
- @Log4j — для Apache Log4j
- @Log4j2 — для Log4j2

3️⃣ Не забывайте про уровень логирования!
Используйте debug для отладки, info для полезных сообщений, warn для предупреждений и error для ошибок.

Вывод: @Slf4j — это удобный инструмент, который избавляет от лишнего кода и упрощает работу с логированием. Если вы еще не используете Lombok для логирования, самое время попробовать!

👉@BookJava
👍10
⚡️ Кастомный toString() в Java – как сделать правильно?

Сегодня поговорим про метод toString() в Java. Казалось бы, мелочь, но грамотная реализация этого метода значительно упрощает отладку и логирование.

Как делать НЕ стоит
Обычная ошибка – использовать toString() по умолчанию или писать его вручную без четкой структуры:


public class User {
private String name;
private int age;

// Ошибочный вариант
@Override
public String toString() {
return "User[name=" + name + ", age=" + age + "]";
}
}

Минусы такого подхода:
- Код громоздкий и трудно читаемый
- При добавлении новых полей легко забыть их добавить в toString()
- Нет удобного форматирования

Как делать правильно
Лучший вариант – использовать String.format() или StringJoiner, но ещё лучше – библиотеку Lombok или Objects.toString():


import lombok.ToString;

@ToString
public class User {
private String name;
private int age;
}


Или без Lombok, но читабельно:


import java.util.Objects;

public class User {
private String name;
private int age;

@Override
public String toString() {
return String.format("User{name='%s', age=%d}", name, age);
}
}

Плюсы:
- Автоматически форматируется
- Читаемый и поддерживаемый код
- Легко расширять

Используйте toString() осознанно, и ваш код станет лучше! Какой способ используете вы?

👉@BookJava
👎41👍1
Утренний рефакторинг с Дженной Ортегой*

На относительно простом примере показываю как можно сделать программу «снова великой». Ключевые стадии рефакторинга, Java, эмулятор и Jenna Ortega в нейросетевом исполнении.

https://habr.com/ru/articles/886890/

👉@BookJava
👍2
🔍Что спрашивают на собеседовании у Middle Java-разработчика

Уже завтра, 5 марта в 19:00 мск — бесплатное открытое собеседование в прямом эфире!

Интервьюер Алексей Ушаровский (Oracle, Сбер) задаст реальные вопросы разработчику-добровольцу и разберёт его ответы. В конце — время вопросов ментору из зала.

Что узнаешь на эфире:
📂 Какие вопросы задают на собеседованиях и зачем

📂 Как подготовиться, чтобы получить достойный оффер

📂 Чего ждут от кандидатов на Middle Java

Запишись на эфир в боте ШОРТКАТ → @shortcut_sh_bot

Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqxddYrJ
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🔥 Почему Optional в Java – не просто контейнер!

Сегодня разберём важную тему: Optional в Java – это не просто удобный способ избежать null, но и мощный инструмент для работы с потоками данных.

🚀 Как правильно использовать Optional?

1️⃣ Избегаем null-чеков
Раньше код был полон if (obj != null), но теперь:

Optional<String> name = Optional.ofNullable(user.getName());
name.ifPresent(System.out::println);

Это делает код чище и понятнее.

2️⃣ Комбинируем с map() и flatMap()
Если у нас есть объект, внутри которого другой объект, а внутри него – ещё один, Optional поможет избежать вложенных if-else:

Optional<String> city = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity);

Всё элегантно и лаконично!

3️⃣ Используем orElse() и orElseGet() правильно
Антипаттерн – всегда выполняет new Object():

User user = optionalUser.orElse(new User());

Лучше такorElseGet() вызовется только если optionalUser пуст:

User user = optionalUser.orElseGet(User::new);

Это особенно важно, если объект тяжёлый в создании.

4️⃣ orElseThrow() – избавляемся от null вообще
Когда отсутствие значения – это ошибка, не бойтесь выбрасывать исключение:

User user = optionalUser.orElseThrow(() -> new RuntimeException("User not found"));

Это делает код безопаснее!

Когда не стоит использовать Optional?
- В полях сущностей (например, JPA) – это может ухудшить производительность.
- Для коллекций – лучше возвращать пустую коллекцию, а не Optional<List<T>>.

А как ты используешь Optional в своём коде? Делись в комментариях! 👇

👉@BookJava
👍8