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

Автор: @energy_c

Реклама на бирже: https://telega.in/c/java_ready
Download Telegram
Почему split(".") не разделяет строку по точке?

На первый взгляд такой код выглядит правильно:
String[] parts =
"api.example.com".split(".");


Но split() принимает не обычную строку-разделитель, а регулярное выражение.

В regex точка означает любой символ. Поэтому выражение "." совпадает практически со всей строкой, а пустые элементы в конце результата split() удаляет.

В результате можно неожиданно получить пустой массив:
System.out.println(
Arrays.toString("a.b".split("."))
);
// []


Чтобы искать именно точку, её нужно экранировать:
String[] parts =
"api.example.com".split("\\.");

System.out.println(
Arrays.toString(parts)
);
// [api, example, com]


Два обратных слеша нужны из-за двойной обработки: сначала Java превращает \\ в один слеш, а затем regex получает выражение \.

Если разделитель приходит из переменной, безопаснее не экранировать его вручную:
String separator = ".";
String regex =
Pattern.quote(separator);

String[] parts = text.split(regex);


Pattern.quote() превращает строку в литеральное регулярное выражение. Это особенно полезно для разделителей вроде точки, вертикальной черты, плюса или скобок.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍4🔥2
Шпаргалка по регулярным выражениям в Java!

Например, \d находит цифру, \w символ слова, а квантификатор {n,m} задаёт минимальное и максимальное количество повторений.

На картинке классы символов, границы строк, флаги Pattern, жадные и ленивые квантификаторы, группы, обратные ссылки и основные методы Pattern и Matcher.

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

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥5👍4
Почему успешная сборка ещё не означает, что Java-код работает правильно?

В этой статье:
• Почему пустой catch может незаметно скрыть реальную ошибку
• Что произойдёт, если переопределить equals(), но забыть про hashCode()
• Как современные возможности Java помогают убрать старые опасные конструкции
• Зачем подключать SpotBugs, PMD и другие проверки ещё до релиза

Полезный разбор ошибок, которые выглядят безобидно, проходят компиляцию, но позже превращаются в настоящие проблемы.

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


👉 Java Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3🔥3
Как аккуратно считать повторения через Map.merge() в Java?

Когда нужно посчитать частоту значений, часто пишут ручную проверку:
Map<String, Integer> clicks = new HashMap<>();

if (clicks.containsKey("login")) {
clicks.put("login", clicks.get("login") + 1);
} else {
clicks.put("login", 1);
}


Код рабочий, но быстро разрастается: проверка, получение старого значения, обновление.

В Java для таких случаев есть merge():
clicks.merge("login", 1, Integer::sum);


Логика такая: если ключа ещё нет, Java положит значение 1.

Если ключ уже есть, Java возьмёт старое значение и объединит его с новым через Integer::sum:
clicks.merge("login", 1, Integer::sum);
clicks.merge("login", 1, Integer::sum);

// login -> 2


Это удобно для счётчиков, статистики, лайков, просмотров, ошибок по типам и любых группировок:
for (String event : events) {
counters.merge(event, 1, Integer::sum);
}


Можно использовать не только сумму:
prices.merge(productId, newPrice, Math::max);


Здесь в мапе останется максимальная цена для каждого товара.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🔥2
Отличная статья для тех, кто хотел попробовать Java не только в backend, но и в Minecraft-моддинге!

В этой статье:
• Как устроен первый проект мода и какие файлы в нём важны
• Чем помогают Fabric, Forge и Mixin при изменении поведения игры
• Как начать с простого примера и понять базовую структуру моддинга

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


👉 Java Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍3🔥3
Шпаргалка по JVM options в Java!

Например, -Xms задаёт начальный размер heap, -Xmx ограничивает максимальный heap, а -XX:+HeapDumpOnOutOfMemoryError помогает получить дамп памяти при падении с OutOfMemoryError.

На картинке JVM options: стандартные параметры запуска, -D system properties, javaagent, non-standard -X options, GC-флаги, heap-настройки, debugging-параметры и performance options.

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

👉 Java Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43🔥3
Опа, тут бывший сеньор одного из IT-отделов Яндекса Игорь Никитин выкатил целый канал про Python — и это лучшее, что есть в рунете по теме.

Качественные гайды. Советы от известных прогеров. Тематические мемасы. Короче, ничего лишнего.

Хватит душить питона, учись его кодить: https://t.me/+IzIPzvoa7p40ZTUy 🐍
😁4
Делаем простой rate limiter!

Иногда нужно ограничить частоту действий: отправку писем, запросы к API, попытки входа или запуск тяжёлой операции. Соберём простой limiter, который разрешает не больше N действий за небольшой промежуток времени.

Для хранения времени запросов подойдёт очередь:
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayDeque;
import java.util.Deque;


Создадим класс:
public class RateLimiter {
private final int limit;
private final Duration window;
private final Deque<Instant> calls = new ArrayDeque<>();


Конструктор:
    public RateLimiter(int limit, Duration window) {
this.limit = limit;
this.window = window;
}


Главный метод будет возвращать true, если действие разрешено:
    public boolean allow() {
Instant now = Instant.now();
Instant border = now.minus(window);

while (!calls.isEmpty() && calls.peekFirst().isBefore(border)) {
calls.removeFirst();
}


Если в окне уже слишком много вызовов, блокируем:
        if (calls.size() >= limit) {
return false;
}

calls.addLast(now);
return true;
}
}


Теперь можно ограничить, например, 3 попытки за 10 секунд:
RateLimiter limiter = new RateLimiter(
3,
Duration.ofSeconds(10)
);


Использование:
if (limiter.allow()) {
System.out.println("Запрос выполнен");
} else {
System.out.println("Слишком много запросов");
}


Такой limiter хранит только актуальные вызовы внутри окна. Старые записи постепенно удаляются из очереди.

Для многопоточного кода метод allow() стоит синхронизировать:
public synchronized boolean allow() {
// та же логика
}


Rate limiter это простой, но очень полезный паттерн для API, авторизации, фоновых задач и защиты от слишком частых действий.

👉 Java Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍3🔥3
Разберём Java records: 7 приёмов для компактных моделей данных!

Records помогают быстро описывать неизменяемые объекты без лишнего шаблонного кода. Эта шпора пригодится для DTO, value objects, событий, ответов API и небольших внутренних моделей, где важны читаемость и предсказуемое поведение.

👉 Java Ready | #шпора
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥53👍3🤝3
На Stepik запустили курс по вайбкодингу c Claude Code

Первым делом вы освоите базу Claude Code и научитесь проектировать полноценные приложения.

После этого перейдёте к более продвинутым инструментам и автоматизации:

➡️Разработаете собственные MCP-серверы и Claude Skills
➡️Автоматизируете разработку с помощью Agent Loops и хуков
➡️Освоите Claude Design, Cowork и Connectors
➡️Построите личную систему знаний на базе Obsidian + Claude Cowork
➡️Научитесь работать с таблицами при помощи Cowork
➡️Перестанете постоянно упираться в лимиты Claude

А в финале получите готовую дорожную карту, полезные лайфхаки и 7 практических способов обхода блокировок Claude Code в России.

🔥 В течении 48 часов действует скидка 25%
Please open Telegram to view this post
VIEW IN TELEGRAM
👎21
Чем полезен List.copyOf() в Java?

Иногда объект получает список извне и сохраняет его в поле:
public Order(List<String> items) {
this.items = items;
}


На первый взгляд всё нормально. Но если внешний код потом изменит список, изменится и состояние Order:
List<String> source = new ArrayList<>();
source.add("book");

Order order = new Order(source);
source.add("phone");


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

Чтобы защититься, можно сделать копию:
this.items = List.copyOf(items);


Теперь объект хранит собственный неизменяемый снимок списка:
public Order(List<String> items) {
this.items = List.copyOf(items);
}


Если исходный список изменится позже, поле внутри Order уже не поменяется:
source.add("phone");

// order всё ещё хранит старый набор


И сам список внутри Order нельзя случайно изменить:
order.items().add("tablet"); // UnsupportedOperationException


Обычно такой список удобно возвращать наружу:
public List<String> items() {
return items;
}


Потому что вызывающий код не сможет незаметно изменить внутреннее состояние объекта.

Важно: List.copyOf() не принимает null-элементы:
List.copyOf(List.of("a", null)); // NullPointerException


List.copyOf() полезен для защитного копирования. Он помогает не отдавать внутреннее состояние объекта под управление внешнего кода.

👉 Java Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2🔥2