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

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

@bookjava

📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


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

РКН clck.ru/3KoGeP
Subscribers
10.1K
Photos
1.1K
Videos
603
Links
1.5K

Showing posts older than #3926 · Back to latest

Older Posts 19 shown
Post #3925 1.54K
Совет по Java 💡

Чтобы сделать большие и сложные цепочки компараторов более читаемыми, мне нравится присваивать компараторы переменным, имена которых начинаются с "by". Таким образом, вызов sorted() становится меньше и читается почти как естественный язык. Кроме того, вы можете использовать статический импорт.

👉@BookJava
  • 👍 9
  • 🔥 4
  • ❤ 1
Post #3923 1.4K
В чем суть принципа DI из SOLID, и почему с ним так много проблем?

DI — это Dependency Inversion Principle, последний принцип из SOLID. Его суть:

🧠 Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те, и другие должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.


🔍 Переводим на практику:

Вместо того чтобы класс сам создавал зависимости (new внутри), он получает их снаружи — через конструктор, сеттер или метод. Это и называется внедрение зависимостей (Dependency Injection).

Пример без DI (нарушение DIP):


class UserService {
private final UserRepository repo = new UserRepository(); // жесткая связка
}


Пример с DI:


class UserService {
private final UserRepository repo;

public UserService(UserRepository repo) {
this.repo = repo;
}
}


Теперь можно легко подменять реализацию UserRepository, например, на InMemoryUserRepository в тестах — и UserService даже не узнает.


⚠️ Почему с этим столько проблем?

1. Избыточность на старте. Для новичков DIP и DI выглядят как «лишние классы и абстракции ни о чём».
2. Сложность в управлении графом зависимостей. Особенно в больших системах, где всё зависит от всего.
3. Контейнеры DI (Spring, Guice, Dagger) могут всё усложнить — магия, ленивая инициализация, прокси, ошибки в рантайме.
4. Соблазн абстрагироваться ради абстракции. Когда вместо пользы получаем тонну интерфейсов без альтернативных реализаций.


💡 Советы:

- Используй DI, но не злоупотребляй абстракциями без нужды.
- Всегда пиши под интерфейс, если есть потенциально 2+ реализации.
- Контейнеры типа Spring делают DI удобным, но важно понимать, что именно они делают под капотом.

📌 DIP — это не про контейнеры, это про независимость и заменяемость.

👉@BookJava
  • 👎 5
  • 👍 2
  • ❤ 1
  • 🤔 1
Post #3922 1.55K
Советы по Java 💡

Как инициализировать collections или map в Java? Конечно, вы можете использовать, например, статическую инициализацию фабрики (`List.of(...)` или `Map.of(...)`).
Но вы также можете воспользоваться функцией "инициализации двойной скобкой"

👉@BookJava
  • 😱 6
  • 👍 2
  • ❤ 1
  • 🔥 1
Post #3921 1.94K
Новая вакансия! Стажёр, мечтающий построить карьеру в ИТ

📍 Локация: вся Россия и всемирная сеть Интернет
График: свободный
Опыт: необязателен, но желание и любопытство — строго необходимо.

📝 Задачи:
– листать свежие стажировки и откликаться по ссылкам,
– читать истории других стажёров,
– заглядывать на вебинары, хакатоны и карьерные мероприятия,
– задавать вопросы и учиться.

💡 От нас:
– возможность трудоустройства в атомной отрасли,
– шанс поработать под руководством топовых ИТ-экспертов
– сообщество таких же увлечённых молодых специалистов.

Подписывайтесь на ИТ-стажировки Росатома и следите за обновлениями.
Telegram ИТ-стажировки Росатома Привет! Здесь публикуются актуальные новости про стажировки в Росатоме. Наш сайт 👉🏻 https://edu.rosatom.ru
  • ❤ 1
Post #3920 1.75K
Совет 💡

Если вы хотите получить сообщение о первопричине, вы можете легко и безопасно получить его с помощью Apache Commons ExceptionUtils. Методы getRootCauseMessage(Exception ex) выдают сообщение в виде {ClassNameWithoutPackage} {ThrowableMessage}

👉@BookJava
  • 👍 7
  • ❤ 1
Post #3918 1.58K
Java spring exception handling | обработка исключений за 5 минут

В этом видео речь пойдет об обработке исключений на уровне контроллера на языке Java. Покажу, какие инструменты есть у Spring.

00:23 - try catch, ResponseEntity
00:47 - наследование ResponseStatusException
01:10 - настройки отображения сообщения, названия ошибки и стек трейс в ответе
01:47 - бросаем ResponseStatusException
02:04 - аннотация @ ExceptionHandler
03:05 - аннотация @ RestControllerAdvice
03:40 - кастомный объект вместо ResponseEntity
04:02 - аннотация @ ResponseStatus

Код можно посмотреть тут: https://github.com/dispikerton/exceptionHandling

источник

👉@BookJava
  • 👍 8
  • ❤ 1
Post #3917 1.45K
Как просуммировать элементы массива?

👉@BookJava
  • 👍 5
  • 🤔 5
  • ❤ 1
Post #3915 1.24K
🚀 Совет по Java API

Периоды дня в форматах java.time

Если вы хотите указать период дня, например «утром», «днем» или «ночью», используйте шаблон форматирования с символом B. 🔥

👉@BookJava
  • 👍 6
  • ❤ 1
Post #3914 1.37K
🧠 Stream API vs. for-loop: когда лучше не использовать Stream

Всё чаще вижу, как даже простые циклы заменяют на Stream API "для красоты". Но в ряде случаев это бьёт по производительности и читаемости.

📌 Пример:


// Было
for (User user : users) {
if (user.isActive()) {
return user;
}
}

// Стало
return users.stream()
.filter(User::isActive)
.findFirst()
.orElse(null);


💡 Выглядит элегантно, но…

⚠️ Проблема: stream() создает итератор, лямбду, объект Optional, плюс возможен autoboxing. А обычный for — просто цикл.

📊 Бенчмарк (JMH):

* for-loop быстрее на ~30-50% на коротких коллекциях (до 1000 элементов).
* На больших коллекциях разница сокращается, но for всё равно стабильнее.

📌 Когда лучше использовать for:

* Нужно выйти из цикла при первом совпадении.
* Важна максимальная производительность.
* Код должен быть суперчитаемым и без лишних аллокаций.

📌 Когда можно Stream:

* Фильтрации, маппинги, группировки — когда логика сложнее.
* Обработка больших потоков с parallelStream() (осторожно!).
* Когда читаемость выигрывает из-за декларативности.

✅ Вывод: Stream API — мощный инструмент, но не замена всему подряд. Иногда простой for — это и быстрее, и понятнее.

👉@BookJava
  • 👍 7
  • 💩 7
  • ❤ 1
Post #3912 1.41K
Абстрактные классы и методы в Java: объяснение за 7 минут

Что такое абстрактные классы и методы в Java, как и зачем их использовать?
Также — в чём разница между абстрактным классом и интерфейсом?

Абстрактные классы могут показаться странной и сложной концепцией в Java, но на самом деле всё довольно просто. Мы объясним их всего за несколько минут в этом видеоуроке для начинающих по Java.

Как создать абстрактный класс или абстрактный метод? Почему вообще стоит использовать абстрактный класс в Java? Чем абстрактный класс отличается от интерфейса?

Улучшайте свои знания Java, наблюдая за живым написанием кода!

Привет, меня зовут Джон! Я ведущий инженер-программист Java с более чем десятилетним опытом работы в индустрии. Мне нравится делиться тем, что я узнал за эти годы, понятным языком — для программистов любого уровня.

👉@BookJava
  • 👍 2
Post #3911 1.56K
Roadmap for Java Developers

👉@BookJava
  • 👎 7
  • 👍 5
Post #3909 1.58K
Совет по Spring Boot 🚀

Еесли вы хотите узнать, когда начинается и заканчивается транзакция #JPA, как повторно использовать существующую транзакцию в @Transactional или шаблоне TransactionTemplate, включите логирование DEBUG для `org.springframework.orm.jpa`.

👉@BookJava
  • 👍 5
  • ❤ 2
Post #3907 1.31K
🧠Принципы SOLID

📌 S — Single Responsibility Principle (SRP)

Класс должен иметь только одну причину для изменения.


// ❌ Плохо: один класс делает и валидацию, и сохранение
class UserService {
void register(User user) {
if (user.email().isBlank()) throw new IllegalArgumentException();
userRepository.save(user);
}
}

// ✅ Хорошо: разбили ответственности
class UserValidator {
void validate(User user) { /*...*/ }
}
class UserService {
void register(User user) {
validator.validate(user);
userRepository.save(user);
}
}



📌 O — Open/Closed Principle (OCP)

Классы открыты для расширения, но закрыты для изменения.


// ✅ Используем Strategy вместо if-else
interface DiscountStrategy {
BigDecimal apply(BigDecimal price);
}
class BlackFridayDiscount implements DiscountStrategy {
public BigDecimal apply(BigDecimal price) { return price.multiply(new BigDecimal("0.8")); }
}
class CheckoutService {
BigDecimal checkout(BigDecimal price, DiscountStrategy strategy) {
return strategy.apply(price);
}
}



📌 L — Liskov Substitution Principle (LSP)

Объекты подклассов должны заменять объекты суперклассов без ошибок.

⚠️ Нарушение LSP вызывает баги, когда подкласс меняет поведение базового класса.


class Bird {
void fly() { /*...*/ }
}
class Ostrich extends Bird {
void fly() { throw new UnsupportedOperationException(); } // ❌ нарушает LSP
}


✅ Решение — выносить общее поведение в интерфейсы по возможностям, а не по наследованию.


📌 I — Interface Segregation Principle (ISP)

Лучше несколько маленьких интерфейсов, чем один жирный.


// ❌ Плохо: интерфейс заставляет имплементировать ненужное
interface Machine {
void print(); void scan(); void fax();
}

// ✅ Хорошо: разделение по возможностям
interface Printer { void print(); }
interface Scanner { void scan(); }



📌 D — Dependency Inversion Principle (DIP)

Модули верхнего уровня не должны зависеть от низкоуровневых. Зависимость — от абстракций.


// ✅ Вместо прямой зависимости от класса — интерфейс
interface NotificationSender {
void send(String message);
}
class EmailSender implements NotificationSender { /*...*/ }
class UserNotifier {
private final NotificationSender sender;
public UserNotifier(NotificationSender sender) {
this.sender = sender;
}
}


💡 Spring идеально подходит для соблюдения DIP — внедрение зависимостей через @Autowired или @Bean.


Если вы соблюдаете SOLID — ваш код легче тестировать, расширять и поддерживать. Но без фанатизма: балансируйте с принципами KISS и YAGNI.

👉@BookJava
  • 👍 7
  • ❤ 3
Post #3905 1.92K
10 полезных функций, которые часто пригождаются продвинутым Java-разработчикам


1. Safe Cast с Optional


public static <T> Optional<T> safeCast(Object obj, Class<T> clazz) {
return clazz.isInstance(obj) ? Optional.of(clazz.cast(obj)) : Optional.empty();
}



2. Таймер производительности (Stopwatch)


public static <T> T measureTime(String label, Supplier<T> supplier) {
long start = System.nanoTime();
T result = supplier.get();
long duration = System.nanoTime() - start;
System.out.printf("[%s] Duration: %d ms%n", label, duration / 1_000_000);
return result;
}



3. Deep Copy через сериализацию


@SuppressWarnings("unchecked")
public static <T extends Serializable> T deepCopy(T object) {
try (
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)
) {
oos.writeObject(object);
try (
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais)
) {
return (T) ois.readObject();
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("Deep copy failed", e);
}
}



4. Рекурсивный поиск файлов с фильтром


public static List<Path> findFiles(Path root, Predicate<Path> filter) throws IOException {
try (Stream<Path> stream = Files.walk(root)) {
return stream.filter(Files::isRegularFile).filter(filter).collect(Collectors.toList());
}
}



5. Универсальный Retry Wrapper


public static <T> T retry(int attempts, Duration delay, Supplier<T> task) {
for (int i = 1; i <= attempts; i++) {
try {
return task.get();
} catch (Exception e) {
if (i == attempts) throw e;
try { Thread.sleep(delay.toMillis()); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }
}
}
throw new RuntimeException("Retry failed");
}



6. Сериализация Map в query string


public static String toQueryString(Map<String, String> params) {
return params.entrySet().stream()
.map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8) + "=" +
URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
}



7. Группировка по произвольному ключу


public static <T, K> Map<K, List<T>> groupBy(Collection<T> items, Function<T, K> classifier) {
return items.stream().collect(Collectors.groupingBy(classifier));
}



8. Метод ожидания условия с таймаутом


public static boolean waitFor(Predicate<Void> condition, Duration timeout, Duration interval) {
long deadline = System.currentTimeMillis() + timeout.toMillis();
while (System.currentTimeMillis() < deadline) {
if (condition.test(null)) return true;
try { Thread.sleep(interval.toMillis()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
}
return false;
}



9. Поиск первого ненулевого значения


@SafeVarargs
public static <T> Optional<T> firstNonNull(Supplier<T>... suppliers) {
for (Supplier<T> supplier : suppliers) {
T value = supplier.get();
if (value != null) return Optional.of(value);
}
return Optional.empty();
}



10. Конвертация Enum в Map


public static <E extends Enum<E>> Map<String, E> enumMap(Class<E> enumClass) {
return Arrays.stream(enumClass.getEnumConstants())
.collect(Collectors.toMap(Enum::name, Function.identity()));
}


👉@BookJava
  • 👍 8
  • 🤡 4
  • 🔥 1
  • 👏 1
  • 🤔 1
Post #3904 1.54K
В чем различия между String и char[]?

👉@BookJava
  • 👍 4
  • 💩 3
  • ❤ 1
Post #3902 1.54K
Можете ли вы назвать методы класса Object?

👉@BookJava
  • 👍 5
  • 🔥 3
  • 💩 2
Post #3901 1.55K
Что такое класс Object?

Разбираем Java-собеседование по кодингу.

👉@BookJava
  • 👍 5
  • 🔥 2
  • 😐 1
Post #3900 1.58K
🔍 Завтра тестовое собеседование с Java-разработчиком

2 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot

Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqxP5g9d
  • ❤ 2
Post #3899 1.39K
Что такое Java?

Разбираем собеседование по Java-кодингу.

👉@BookJava
  • 👍 7
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →