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


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

РКН clck.ru/3KoGeP
Download Telegram
Совет по @SpringData: при использовании интерфейсных проекций вы можете получить доступ к вложенным объектам, добавив `path` к методу getter. Посмотрите, как метод getDepartmentDeptName получает deptName из сущности Department.

#Java

👉@BookJava
👍9
Совет по Spring Boot💡

Улучшите сборку образа контейнера @springboot с помощью #Jlink! 🔥

https://paketo.io/docs/howto/java/#install-a-minimal-jre-with-jlink

#SpringBoot #Java

👉@BookJava
5👍1
Советы по Spring Batch 💡

Оптимизируйте свои шаги в @SpringBatch с помощью параметра `startLimit` и определите, сколько раз можно запустить шаг. 🔥

#Java #SpringBatch

👉@BookJava
👍4
This media is not supported in your browser
VIEW IN TELEGRAM
Знали ли вы, что вы можете перетащить класс или запись #Java в @vaadin Copilot, чтобы автоматически сгенерировать для него форму? Теперь вы знаете

👉@BookJava
👍7
Java Language Futures - Fall 2024 Edition

0:00 - Intro
3:54 - Records
9:14 - Sealed classes
11:22 - Pattern matching
20:00 - Data Oriented Programming
29:00 - Implicitly declared classes & instance main methods
33:20 - with Expressions
38:20 - Flexible constructor bodies
48:10 - What's next
50:53 - Conclusion

https://www.youtube.com/watch?v=NNPN5tvjzqA

👉@BookJava
👍4
💡Совет: по умолчанию ленивую загрузку в @Hibernate можно использовать только для отношений, но не для простых (базовых) атрибутов.

Чтобы она работала и для полей, необходимо использовать байткод-энхансмент через плагин. В этом случае поля, отмеченные как lazy, будут загружаться при первом обращении к ним.

#Java #JPA

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
#Java springboot
Совет: Нужно быстро собрать разрозненные данные в POST-запросе?

Просто создайте встроенную record в вашем
@RestController и используйте её как @RequestBody.

Не нужно определять DTO в отдельном классе – record будет видна только внутри этого контроллера. 🚀

👉@BookJava
👍10
Media is too big
VIEW IN TELEGRAM
Хранилище файлов. Java + WebDav

Java + WebDav - загружаем файл на webdav через Rest запрос.

00:00 Приветствие
00:34 Spring Init
00:55 Docker Hub
01:54 docker-compose
04:25 webdav.conf
06:00 application.yaml
06:50 Sardine
07:36 WebDavConfig
09:15 WebConfig
11:40 FileService
14:09 Controller
17:22 Docker Fix
17:47 Postman
18:16 что не так?
20:46 Подписывайтесь

источник

👉@BookJava
👍5
💡Совет: @TransactionalEventListener — это специализированная версия @EventListener, которая прослушивает событие и ждёт завершения текущей транзакции, прежде чем сработать.
Ожидание согласованного состояния базы данных позволяет безопаснее реагировать на изменения, внесённые в БД

#Java #springboot

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍124
☕️ Spring Core: Зачем нужна аннотация @Bean?

Если вы работаете со Spring, вы видите эту аннотацию постоянно. Но чем она отличается от простого навешивания @Component над классом? Давайте разберем.

💡 Что это такое?

Аннотация @Bean используется в методах конфигурационных классов (помеченных @Configuration). Она говорит Spring-контейнеру:

"Эй, Spring! Выполни этот метод, возьми то, что он вернет, и сохрани этот объект у себя в контексте (ApplicationContext). Управляй им как бином".


🛠 Как это выглядит?


@Configuration
public class AppConfig {

// Мы явно создаем объект и отдаем его Спрингу
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper(); // Например, библиотека Jackson
}
}




🔥 Когда использовать @Bean, а когда @Component?

Это самый частый вопрос на собеседованиях.

1. Используйте @Component@Service, @Repository), когда:

- Это ваш класс. Вы имеете доступ к исходному коду.
- Вам нужна магия автоматического сканирования (component scanning). Вы просто ставите аннотацию над классом, и Spring сам его находит.

2. Используйте @Bean, когда:

- Сторонние библиотеки. Вы не можете зайти в класс ObjectMapper (из Jackson) или AmazonS3Client и написать там @Component, потому что это чужой код (read-only). Чтобы добавить такой объект в контекст Spring, вы создаете для него метод с @Bean.
- Сложная логика создания. Если создание объекта требует условий (if/else) или сложной конфигурации, проще описать это в методе явно.

⚙️ Фишки @Bean

- Имена: По умолчанию имя бина совпадает с именем метода. Можно изменить: @Bean("myCoolBean").
- Init/Destroy: Можно указать методы, которые сработают при создании или удалении бина: @Bean(initMethod = "init", destroyMethod = "cleanup").
- Зависимости: Если методу с @Bean нужны аргументы, Spring автоматически найдет и подставит их из контекста.

Итог: @Component - для автоматизации своих классов, @Bean - для ручного контроля и чужих библиотек.


#Java #Spring #SpringBoot #Coding #Education

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3
🧵 String.join(): Склеиваем строки без боли

Помните те времена, когда для объединения списка строк через запятую приходилось писать циклы, использовать StringBuilder, а потом еще и аккуратно удалять последний разделитель? 🤯

Начиная с Java 8, у нас есть элегантный статический метод String.join, который делает код чистым и читаемым.

🛠 Как это работает?

Метод принимает разделитель (delimiter) и элементы, которые нужно склеить. Элементами могут быть как просто перечисление строк (varargs), так и любая коллекция (Iterable).

1️⃣ Пример с перечислением строк:


String result = String.join(" -> ", "Wake up", "Code", "Sleep");

System.out.println(result);
// Вывод: Wake up -> Code -> Sleep


2️⃣ Пример с коллекцией (List, Set):


List<String> langs = Arrays.asList("Java", "Kotlin", "Groovy");

// Больше никаких циклов!
String output = String.join(" | ", langs);

System.out.println(output);
// Вывод: Java | Kotlin | Groovy


🧐 Важные нюансы:

- Null-safe (частично): Если сам список или массив равен null, вы получите NullPointerException. Но если null является одним из элементов списка, метод просто преобразует его в строку "null".
- Под капотом: Метод использует StringJoiner (еще один класс из Java 8), что обеспечивает неплохую производительность по сравнению с обычной конкатенацией через +.

🚀 Когда использовать?

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

Если же вы работаете со Stream API, то лучше подойдет коллектор:
.collect(Collectors.joining(", "))


#Java #Core #Tips #CleanCode

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Функциональные интерфейсы: Магия за кулисами Лямбд

Если вы используете лямбды (а вы наверняка их используете), значит, вы работаете с функциональными интерфейсами. Давайте разберем, что это такое, зачем нужна аннотация и какие интерфейсы вы обязаны знать наизусть.

🎯 Что это такое?

Функциональный интерфейс - это интерфейс, который содержит ровно один абстрактный метод.

Именно это ограничение позволяет компилятору превращать лямбда-выражение в экземпляр этого интерфейса.

💙 Примечание: В интерфейсе может быть сколько угодно default или static методов. Главное - только один абстрактный.

📝 Аннотация @FunctionalInterface

Ставить её над интерфейсом не обязательно, но хорошим тоном считается ставить.
Зачем? Она работает как защита от дурака: если вы или ваш коллега случайно добавите второй абстрактный метод в интерфейс, компилятор сразу выдаст ошибку, не дожидаясь падения кода в местах использования лямбд.



🧰 Шпаргалка: "Великолепная четверка"

В пакете java.util.function уже есть готовые интерфейсы на 99% случаев жизни. Не пишите свои велосипеды, пока не выучите эти:

1. Predicate <T>
💙Что делает: Проверяет условие.
💙 Метод: boolean test(T t)
💙 Где нужен: Фильтрация стримов (`filter`), проверки.


2. Consumer <T>
💙 Что делает: "Потребляет" объект, ничего не возвращая.
💙 Метод: void accept(T t)
💙 Где нужен: Вывод на экран, запись в БД, forEach.


3. Supplier <T>
💙 Что делает: "Поставляет" объект (из ниоткуда), ничего не принимая.
💙 Метод: T get()
💙 Где нужен: Ленивая инициализация, генерация значений, orElseGet.


4. Function <T, R>
💙 Что делает: Превращает объект типа T в объект типа R.
💙 Метод: R apply(T t)
💙 Где нужен: Преобразование данных, map в стримах.


💻 Пример в коде


@FunctionalInterface
interface Converter {
int stringToInt(String s);
}

public class Main {
public static void main(String[] args) {
// 1. Создаем реализацию через лямбду
Converter converter = str -> Integer.parseInt(str);

// 2. Использование стандартного Consumer
java.util.function.Consumer<Integer> print = x -> System.out.println("Result: " + x);

int result = converter.stringToInt("123");
print.accept(result); // Вывод: Result: 123
}
}



🔥 Итог

Функциональные интерфейсы - это контракт для лямбда-выражений. Используйте стандартные из java.util.function, чтобы ваш код был понятен другим разработчикам без лишних документаций.

#Java #Core #Lambda #FunctionalProgramming

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍1
🚀 Функциональные интерфейсы: Level Up

В первой части мы разобрали «Великолепную четверку» (Predicate, Consumer, Supplier, Function). Но что делать, если нужно принять два аргумента? Или если тип входа и выхода совпадает, и лень писать лишний код?

Для этого в Java есть Bi-версии и Операторы.

👯 Семейство «Bi» (Два аргумента)

Стандартные интерфейсы принимают только один параметр. Если вам нужно обработать пару значений (например, ключ и значение из Map), используйте приставку Bi.

1. BiPredicate <T, U>
💙 Метод: boolean test(T t, U u)
💙 Пример: Проверить, что длина строки T больше числа U.


2. BiConsumer <T, U>
💙 Метод: void accept(T t, U u)
💙 Пример: map.forEach((k, v) -> ...) - классический пример использования.


3. BiFunction <T, U, R>
💙 Метод: R apply(T t, U u)
💙 Пример: Сложить число T и число U, получить результат R.



🔄 Семейство «Operator» (Один и тот же тип)

Часто бывает, что вы преобразуете объект, не меняя его тип (String -> String, int -> int). Писать Function<String, String> - слишком длинно.

1. UnaryOperator <T>
💙 Наследник Function<T, T>.
💙 Пример: str -> str.toUpperCase() (принимает строку, возвращает строку).


2. BinaryOperator <T>
💙 Наследник BiFunction<T, T, T>.
💙 Пример: (a, b) -> a + b (два числа на вход, одно число на выход). Именно он используется в Stream.reduce.


Осторожно с боксингом!

Дженерики (<T>) работают только с объектами. Если вы используете Function<Integer, Integer> для математики, Java будет постоянно распаковывать и запаковывать int в Integer, что бьет по производительности.

Для примитивов есть свои спецназовцы:

💙 IntPredicate, LongConsumer, DoubleFunction и т.д.
💙 Правило: Если работаете с числами - всегда ищите примитивный аналог интерфейса.

💻 Пример в коде


import java.util.function.*;

public class AdvancedLambdas {
public static void main(String[] args) {
// 1. BinaryOperator: объединяем две строки
BinaryOperator<String> concat = (s1, s2) -> s1 + " " + s2;
System.out.println(concat.apply("Hello", "Java"));

// 2. BiPredicate: проверяем, начинается ли строка с префикса
BiPredicate<String, String> startsWith = (str, prefix) -> str.startsWith(prefix);
System.out.println(startsWith.test("Telegram", "Tele")); // true

// 3. IntUnaryOperator: работаем с примитивами без лишних объектов
IntUnaryOperator square = x -> x * x;
System.out.println(square.applyAsInt(5)); // 25
}
}



🔥 Итог

💙 Нужно 2 аргумента? Ищите Bi.
💙 Тип входа и выхода совпадает? Ищите Operator.
💙 Работаете с int/long/double? Ищите интерфейсы с префиксом типа.

#Java #AdvancedJava #FunctionalProgramming

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
6