Java Ready | Программирование
8.8K subscribers
1.35K photos
74 videos
1 file
709 links
Авторский канал по разработке на Java.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!

Автор: @energy_c

Реклама на бирже: https://telega.in/c/java_ready
Download Telegram
Почему Stream.toList() может сломать старый код?

В Java часто собирают stream в список:
List<String> names = users.stream()
.map(User::name)
.toList();


Выглядит почти так же, как старый вариант через Collectors:
List<String> names = users.stream()
.map(User::name)
.collect(Collectors.toList());


Но есть важное отличие.

Stream.toList() возвращает неизменяемый список:
List<String> names = users.stream()
.map(User::name)
.toList();

names.add("admin"); // UnsupportedOperationException


Если список нужен только для чтения, это даже плюс:
return users.stream()
.filter(User::active)
.map(User::name)
.toList();


Так код явно показывает, что результат не должен случайно меняться после сборки.

Но если дальше список нужно дополнять, лучше создать изменяемую коллекцию явно:
List<String> names = users.stream()
.map(User::name)
.collect(Collectors.toCollection(ArrayList::new));


Или сделать копию:
List<String> names = new ArrayList<>(
users.stream().map(User::name).toList()
);


👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍4🔥3
Шпаргалка по Spring-аннотациям в Java!

Например, @RestController объединяет контроллер и @ResponseBody, а @Autowired связывает зависимости внутри Spring-компонента.

На картинке основные Spring Boot, Web и Framework-аннотации: @SpringBootApplication, @Controller, @RequestMapping, @PathVariable, @Configuration, @ComponentScan, @Service, @Bean, @Primary, @Profile и другие.

Сохрани, чтобы не потерять!

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥5👍4
Делаем простой retry для нестабильной операции в Java!

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

Опишем функциональный интерфейс для операции:
@FunctionalInterface
interface ThrowingSupplier<T> {
T get() throws Exception;
}


Теперь зададим количество попыток:
int attempts = 3;


И задержку между ними:
Duration delay = Duration.ofMillis(300);


Базовая идея такая:
try {
return action.get();
} catch (Exception e) {
Thread.sleep(delay.toMillis());
}


Но нужно сохранить последнюю ошибку, если все попытки закончились неудачей:
Exception lastError = null;


Соберём retry в метод:
static <T> T retry(
ThrowingSupplier<T> action,
int attempts,
Duration delay
) throws Exception {
Exception lastError = null;

for (int i = 1; i <= attempts; i++) {
try {
return action.get();
} catch (Exception e) {
lastError = e;

if (i < attempts) {
Thread.sleep(delay.toMillis());
}
}
}

throw lastError;
}


Теперь можно обернуть нестабильную операцию:
String response = retry(
() -> loadFromRemoteApi(),
3,
Duration.ofMillis(300)
);


Если операция сработает со второй или третьей попытки, код продолжит выполнение. Если нет, наружу уйдёт последняя ошибка.

В production-коде к retry часто добавляют экспоненциальную задержку, логирование и ограничение по типам исключений.

👉 Java Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍3🔥2
Media is too big
VIEW IN TELEGRAM
Java Code Geeks — огромная база туториалов и примеров по Java!

На сайте собраны материалы по Core Java, Java 8/9, concurrency, NIO, logging, design patterns, exceptions, JUnit, Mockito, Spring Boot, Spring MVC, Spring Security, Hibernate, JPA, JDBC, JavaFX и другим темам. Это не одностраничный справочник, а большая база статей и практических примеров: можно листать разделы, открывать конкретные технологии и быстро находить готовые разборы под реальные задачи backend-разработки.

Оставляю ссылочку: Java Code Geeks


👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍4🔥4
Как сортировать в Java, если в данных бывают null?

Обычная сортировка по полю выглядит просто:
users.sort(Comparator.comparing(User::name));


Но если name() у какого-то пользователя вернёт null, сортировка может упасть с NullPointerException.

Например:
record User(String name) {}

var users = new ArrayList<>(List.of(
new User("Bob"),
new User(null),
new User("Ann")
));


Для таких случаев в Comparator есть специальные обёртки:
Comparator.nullsLast(String::compareTo)


Теперь null можно отправить в конец:
users.sort(Comparator.comparing(
User::name,
Comparator.nullsLast(String::compareTo)
));


Результат будет предсказуемым:
Ann
Bob
null


Если null нужно поставить в начало, есть nullsFirst:
users.sort(Comparator.comparing(
User::name,
Comparator.nullsFirst(String::compareTo)
));


То же самое удобно для дат, email, optional-полей из базы и данных из внешних API:
orders.sort(Comparator.comparing(
Order::paidAt,
Comparator.nullsLast(Comparator.naturalOrder())
));


Так сортировка явно показывает бизнес-правило: пустые значения не ломают код, а уходят туда, куда нужно.

Если поле для сортировки может быть null, лучше сразу описать это через nullsFirst/nullsLast, а не надеяться, что данные всегда идеальные.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2🔥2
Делаем дедупликацию событий на Java!

Если webhook, очередь или внешний сервис повторно присылает одно и то же событие, бизнес-логика не должна выполняться дважды. Соберём простой обработчик, который запоминает eventId и пропускает дубли.

В этой задаче:
• Храним обработанные id в Set;
• Используем add() как проверку на повтор;
• Выполняем действие только для новых событий.


Такой подход помогает избежать повторных списаний, дублей уведомлений и лишней обработки при retry-механиках.

👉 Java Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍3🔥2
Отличная статья про создание собственного Spring Boot 3 starter’а на Java!

В этой статье:
• Как starter превращается в отдельный переиспользуемый блок конфигурации
• Как добавить автоконфигурацию, default-настройки и EnvironmentPostProcessor
• Как собрать стартер и подключить его к обычному Spring Boot-приложению

Продолжай читать на Habr!


👉 Java Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Dev.java — ресурс по современной Java!

На сайте собраны материалы от Java-команды: Getting Started, основы языка, Collections Framework, Stream API, Virtual Threads, JShell, инструменты сборки, IDE, новые возможности платформы и отдельные разделы для более глубокого изучения. Хорошо подходит не только новичкам, но и тем, кто хочет освежить современную Java без случайных устаревших примеров.

Оставляю ссылочку: dev.java

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75🔥5
Делаем простой rate limiter на Java!

Иногда нужно ограничить частоту действий: отправку кода подтверждения, вызов команды, обращение к endpoint или повторную отправку формы. Для базового варианта можно использовать очередь с временем последних успешных вызовов.

В этой задаче:
• храним timestamps действий;
• удаляем устаревшие записи;
• проверяем размер окна;


Такой вариант хорошо подходит для понимания идеи sliding window и небольших локальных сценариев.

👉 Java Ready | #задача
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🔥1
Делаем простой TTL-кэш на Java!

Иногда значение нужно хранить не навсегда, а только короткое время: ответ API, результат вычисления или временную настройку.

Опишем запись кэша:
record Entry<T>(T value, long expiresAt) {}


Создадим хранилище:
Map<String, Entry<String>> cache = new HashMap<>();


Добавим значение с временем жизни:
void put(String key, String value, long ttlMs) {
cache.put(key, new Entry<>(
value,
System.currentTimeMillis() + ttlMs
));
}


Теперь достанем значение:
String get(String key) {
var entry = cache.get(key);

if (entry == null) {
return null;
}

if (entry.expiresAt() < System.currentTimeMillis()) {
cache.remove(key);
return null;
}

return entry.value();
}


Проверка:
put("token", "abc", 1000);

System.out.println(get("token"));


Ожидаемый вывод:
abc


После истечения TTL метод вернёт null, а устаревшая запись удалится из Map.

👉 Java Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍4🔥3👎1
Шпаргалка по Maven!

Например, mvn test запускает тесты, mvn package собирает артефакт, а mvn dependency:tree показывает дерево зависимостей проекта.
На картинке основные Maven-команды, фазы lifecycle, полезные параметры командной строки, локальный репозиторий, Maven Central и популярные плагины: help, dependency, compiler, version, wrapper, Spring Boot и exec.

Сохрани, чтобы не потерять!

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍6🔥5