На картинке показаны основные состояния Thread: New, Runnable, Running, Blocked, Waiting, Time Waiting и Terminated.
Например, когда поток только создан через new Thread(...), он находится в состоянии New.
После вызова start() поток переходит в активную зону и может быть выбран планировщиком для выполнения.
Если поток ждёт освобождения lock, он попадает в Blocked.
Если поток ждёт сигнал от другого потока, например через wait() или join(), он переходит в Waiting.
А если ожидание ограничено по времени, например через sleep() или wait(timeout), это уже Timed Waiting.
Сохрани, чтобы быстрее понимать многопоточность в Java!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍2🔥2
Например,
sealed class позволяет жёстко контролировать наследование, а permits явно указывает, какие классы могут расширять базовый тип.На картинке — краткая шпаргалка по sealed, non-sealed и final классам, а также правилам построения закрытой иерархии в Java 17.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11🔥5👍3
Знаете, что в Java можно писать отрицательные проверки в Stream API без ! внутри lambda?
Часто код выглядит так:
Работает, но когда условий становится больше, такие отрицания начинают хуже читаться.
В Java есть Predicate.not():
Так сразу видно: оставить все строки, которые не blank.
Например:
Это удобно для фильтрации имён, email, тегов, параметров запроса, строк из файлов и любых пользовательских данных.
Особенно хорошо читается вместе с method reference:
Важно только не превращать это в головоломку: если условие сложное, лучше вынести его в отдельный метод с понятным названием.
Так код в stream-цепочках становится аккуратнее и легче читается.
👉 Java Ready | #совет
Часто код выглядит так:
.filter(name -> !name.isBlank())
Работает, но когда условий становится больше, такие отрицания начинают хуже читаться.
В Java есть Predicate.not():
.filter(Predicate.not(String::isBlank))
Так сразу видно: оставить все строки, которые не blank.
Например:
List<String> names = users.stream()
.map(User::name)
.filter(Objects::nonNull)
.filter(Predicate.not(String::isBlank))
.toList();
Это удобно для фильтрации имён, email, тегов, параметров запроса, строк из файлов и любых пользовательских данных.
Особенно хорошо читается вместе с method reference:
Predicate.not(String::isEmpty)
Predicate.not(Collection::isEmpty)
Predicate.not(Optional::isEmpty)
Важно только не превращать это в головоломку: если условие сложное, лучше вынести его в отдельный метод с понятным названием.
Так код в stream-цепочках становится аккуратнее и легче читается.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10🔥4👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Этот репозиторий представляет собой большой структурированный ресурс по Java, в котором собраны основные темы языка простым и понятным языком. Вместо просмотра десятков статей можно открыть один репозиторий и последовательно изучать материал.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9❤4👍2
Фильтруем список задач через Stream API в Java!
Допустим, у нас есть список задач, и нужно получить только те, которые ещё не выполнены.
Создадим простой record:
Теперь подготовим список:
Можно пройтись циклом и вручную собрать новый список:
Но для такой задачи хорошо подходит Stream API:
filter оставляет только элементы, которые проходят условие.
В нашем случае это задачи, у которых done() возвращает false.
Выведем результат:
Получим только активные задачи:
Такой подход удобно использовать не только для задач, но и для заказов, пользователей, товаров, уведомлений или любых списков объектов.
Например, можно выбрать только оплаченные заказы:
filter это базовый, но очень полезный инструмент Stream API для отбора данных по условию.
👉 Java Ready | #практика
Допустим, у нас есть список задач, и нужно получить только те, которые ещё не выполнены.
Создадим простой record:
record Task(String title, boolean done) {}Теперь подготовим список:
List<Task> tasks = List.of(
new Task("Read docs", false),
new Task("Write tests", true),
new Task("Fix bug", false)
);
Можно пройтись циклом и вручную собрать новый список:
List<Task> active = new ArrayList<>();
for (Task task : tasks) {
if (!task.done()) {
active.add(task);
}
}
Но для такой задачи хорошо подходит Stream API:
List<Task> active = tasks.stream()
.filter(task -> !task.done())
.toList();
filter оставляет только элементы, которые проходят условие.
В нашем случае это задачи, у которых done() возвращает false.
Выведем результат:
active.forEach(System.out::println);
Получим только активные задачи:
Task[title=Read docs, done=false]
Task[title=Fix bug, done=false]
Такой подход удобно использовать не только для задач, но и для заказов, пользователей, товаров, уведомлений или любых списков объектов.
Например, можно выбрать только оплаченные заказы:
List<Order> paid = orders.stream()
.filter(Order::isPaid)
.toList();
filter это базовый, но очень полезный инструмент Stream API для отбора данных по условию.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍3🔥3👎1
Шпаргалка по Date and Time API в Java!
На картинке собраны основные вещи по java.time: LocalDate, LocalTime, LocalDateTime, Period, Duration и DateTimeFormatter.
Например, LocalDate используют для даты без времени, LocalTime — для времени без даты, а LocalDateTime — когда нужно хранить и дату, и время вместе.
Ещё полезно помнить, что классы из java.time неизменяемые. Если вызвать plusDays() или minusMonths(), старый объект не изменится, Java вернёт новый.
Это удобно для API, логов, расписаний, бронирований, отчётов и любых задач, где нужно аккуратно работать с датами.
Сохрани, чтобы не путаться между Date, Calendar и нормальным java.time!
👉 Java Ready | #ресурс
На картинке собраны основные вещи по java.time: LocalDate, LocalTime, LocalDateTime, Period, Duration и DateTimeFormatter.
Например, LocalDate используют для даты без времени, LocalTime — для времени без даты, а LocalDateTime — когда нужно хранить и дату, и время вместе.
Ещё полезно помнить, что классы из java.time неизменяемые. Если вызвать plusDays() или minusMonths(), старый объект не изменится, Java вернёт новый.
Это удобно для API, логов, расписаний, бронирований, отчётов и любых задач, где нужно аккуратно работать с датами.
Сохрани, чтобы не путаться между Date, Calendar и нормальным java.time!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥5👍4
Знаете, что в Java можно удобно форматировать многострочный текст через text blocks?
Если нужно собрать письмо, SQL-запрос, JSON или шаблон сообщения, обычные строки быстро становятся шумными:
В современной Java можно использовать text blocks:
Так текст выглядит почти так же, как итоговый результат.
Это удобно для SQL:
И для сообщений пользователю:
Главный плюс меньше \n, кавычек, конкатенации и случайных ошибок в форматировании.
Важно только не использовать text blocks как замену нормальной сериализации JSON или безопасных SQL-параметров.
Для данных из пользователя всё равно нужны ObjectMapper, prepared statements и экранирование там, где это требуется.
👉 Java Ready | #совет
Если нужно собрать письмо, SQL-запрос, JSON или шаблон сообщения, обычные строки быстро становятся шумными:
String json = "{\n" +
" \"name\": \"" + name + "\",\n" +
" \"active\": true\n" +
"}";В современной Java можно использовать text blocks:
String json = """
{
"name": "%s",
"active": true
}
""".formatted(name);
Так текст выглядит почти так же, как итоговый результат.
Это удобно для SQL:
String sql = """
SELECT id, email, created_at
FROM users
WHERE active = true
ORDER BY created_at DESC
""";
И для сообщений пользователю:
String message = """
Hello, %s!
Your order #%d is ready.
""".formatted(name, orderId);
Главный плюс меньше \n, кавычек, конкатенации и случайных ошибок в форматировании.
Важно только не использовать text blocks как замену нормальной сериализации JSON или безопасных SQL-параметров.
Для данных из пользователя всё равно нужны ObjectMapper, prepared statements и экранирование там, где это требуется.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3🔥3
В этом посте покажу, как с помощью
Files.walk и Stream API искать файлы по маске, обходить большие директории и даже считать общий размер — на чистой Java, без лишних зависимостей.Сегодня рассмотрим:
• Как рекурсивно искать файлы и папки.
• Как фильтровать по расширению или маске.
• И посчитаем общий размер всех файлов.
Этот способ в разы лучше и производительней чем старый
File.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2🔥2🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
Этот репозиторий отлично подойдёт тем, кто начинает изучать Java или хочет системно повторить базу. Материал подан простым языком и охватывает ключевые темы, без которых сложно двигаться дальше. Особенно удобно, что всё собрано в формате понятного конспекта с примерами.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍4🔥2
Почему Objects.requireNonNullElse() иногда лучше ручного if?
Когда значение может быть null, часто пишут так:
Код рабочий, но для простого fallback выглядит тяжеловато.
В Java можно записать короче:
Если user.name() не null, вернётся оно.
Если там null, вернётся "Guest".
Есть ещё ленивый вариант:
Он полезен, если значение по умолчанию нужно вычислять не всегда.
requireNonNullElse() это аккуратный способ задать fallback без лишнего if.
👉 Java Ready | #совет
Когда значение может быть null, часто пишут так:
String name = user.name();
if (name == null) {
name = "Guest";
}
Код рабочий, но для простого fallback выглядит тяжеловато.
В Java можно записать короче:
String name = Objects.requireNonNullElse(
user.name(),
"Guest"
);
Если user.name() не null, вернётся оно.
Если там null, вернётся "Guest".
Есть ещё ленивый вариант:
String name = Objects.requireNonNullElseGet(
user.name(),
() -> loadDefaultName()
);
Он полезен, если значение по умолчанию нужно вычислять не всегда.
requireNonNullElse() это аккуратный способ задать fallback без лишнего if.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍4🔥3
Напоминалка по Spring REST-аннотациям!
Например,
На картинке шпаргалка по аннотациям Spring REST: контроллеры, маршруты, параметры запроса, path variables, request body и response-логика.
Сохрани, чтобы не потерять!
👉 Java Ready | #ресурс
Например,
@RestController используют для REST API, @GetMapping и @PostMapping связывают методы с HTTP-запросами, а @RequestBody помогает получить JSON из тела запроса.На картинке шпаргалка по аннотациям Spring REST: контроллеры, маршруты, параметры запроса, path variables, request body и response-логика.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤5🔥3
Фильтруем ошибки из логов через Stream API!
Представим, что у нас есть список логов, и нужно быстро достать только сообщения с уровнем ERROR.
Создадим простую модель:
Можно пройтись обычным циклом:
Но через Stream API это читается компактнее:
filter оставляет только ошибки.
map превращает объект лога в текст сообщения.
В результате получим:
Такой подход удобно использовать для логов, событий, уведомлений, заказов, пользователей и любых списков, где нужно сначала отфильтровать данные, а потом достать нужное поле.
👉 Java Ready | #практика
Представим, что у нас есть список логов, и нужно быстро достать только сообщения с уровнем ERROR.
Создадим простую модель:
record LogEntry(String level, String message) {}
Подготовим данные:
List<LogEntry> logs = List.of(
new LogEntry("INFO", "User opened page"),
new LogEntry("ERROR", "Payment failed"),
new LogEntry("WARN", "Slow response"),
new LogEntry("ERROR", "Database timeout")
);Можно пройтись обычным циклом:
List<String> result = new ArrayList<>();
for (LogEntry log : logs) {
if (log.level().equals("ERROR")) {
result.add(log.message());
}
}
Но через Stream API это читается компактнее:
List<String> result = logs.stream()
.filter(log -> log.level().equals("ERROR"))
.map(LogEntry::message)
.toList();
filter оставляет только ошибки.
map превращает объект лога в текст сообщения.
В результате получим:
[Payment failed, Database timeout]
Такой подход удобно использовать для логов, событий, уведомлений, заказов, пользователей и любых списков, где нужно сначала отфильтровать данные, а потом достать нужное поле.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤3🔥3
Здесь собраны 20 основных направлений: от переменных, циклов и ООП до многопоточности, работы с БД, Spring Boot, JVM и современных возможностей Java.
Используйте её как roadmap для обучения, чек-лист для повторения или ориентир при подготовке к собеседованиям.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍2🔥2
Сидеть и работать в корпорации — страшно, жизнь-то мимо проходит. Уходить строить бизнес — страшно, а вдруг прогорит. Один из вариантов — разрабатывать свой пет-проект по вечерам. Многие успешные компании, например, Twitter, создавались именно так. Это не значит, что ваш проект обязательно заработает миллиарды, но заработать больше, чем в найме, и получить ценный опыт — вполне реально.
Перед началом разработки появляется множество вопросов, например:
• Как выбрать идею для пет-проекта?
• Что нужно знать про маркетинг
• Как запуститься и довести до первых продаж не имея бюджета на рекламу?
В телеграм-канале «Твой пет проект», Михаил Табунов делится своим опытом с разработчиками и менеджерами.
Он рассказывает, где искать идею для нового проекта, что нужно знать о маркетинге, как запустить стартап и привлечь первых 10 клиентов, а также о многих других важных вещах.
Подписывайтесь на «Твой пет проект», получайте пользу от практиков рынка!
https://t.me/+8Frwa03ciVlhNTky
Перед началом разработки появляется множество вопросов, например:
• Как выбрать идею для пет-проекта?
• Что нужно знать про маркетинг
• Как запуститься и довести до первых продаж не имея бюджета на рекламу?
В телеграм-канале «Твой пет проект», Михаил Табунов делится своим опытом с разработчиками и менеджерами.
Он рассказывает, где искать идею для нового проекта, что нужно знать о маркетинге, как запустить стартап и привлечь первых 10 клиентов, а также о многих других важных вещах.
Подписывайтесь на «Твой пет проект», получайте пользу от практиков рынка!
https://t.me/+8Frwa03ciVlhNTky
Telegram
Твой пет проект
Канал про то, как создать свой маленький свечной заводик
Пишу про:
- Запуски и как сделать первые 10 продаж
- Прожарка идей
- Кейсы роста и ведения проекта параллельно с работой
Автор - Михаил Табунов - @bossofyourboss
Связь @to_baza_education
Пишу про:
- Запуски и как сделать первые 10 продаж
- Прожарка идей
- Кейсы роста и ведения проекта параллельно с работой
Автор - Михаил Табунов - @bossofyourboss
Связь @to_baza_education
Считаем частоту слов через Stream API!
Иногда нужно понять, сколько раз каждое значение встречается в списке: слова в тексте, статусы заказов, ошибки в логах или действия пользователей.
Допустим, есть список слов:
Можно вручную создать Map и увеличивать счётчик:
Но через Stream API это можно записать короче:
Function.identity() означает: группируем элементы по самому значению.
А Collectors.counting() считает, сколько элементов попало в каждую группу.
Результат будет таким:
Такой подход удобно использовать для аналитики, логов, статистики, тегов, категорий и любых повторяющихся значений.
👉 Java Ready | #практика
Иногда нужно понять, сколько раз каждое значение встречается в списке: слова в тексте, статусы заказов, ошибки в логах или действия пользователей.
Допустим, есть список слов:
List<String> words = List.of(
"java", "spring", "java", "api", "spring", "java"
);
Можно вручную создать Map и увеличивать счётчик:
Map<String, Long> result = new HashMap<>();
for (String word : words) {
result.put(word, result.getOrDefault(word, 0L) + 1);
}
Но через Stream API это можно записать короче:
Map<String, Long> result = words.stream()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()
));
Function.identity() означает: группируем элементы по самому значению.
А Collectors.counting() считает, сколько элементов попало в каждую группу.
Результат будет таким:
{spring=2, java=3, api=1}
Такой подход удобно использовать для аналитики, логов, статистики, тегов, категорий и любых повторяющихся значений.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3🔥3
Выражение
arr[i] используется для доступа к элементу массива по индексу. Запись arr[i] = value изменяет значение элемента по указанному индексу.На картинке показаны базовые операции с массивами, которые часто используются в практике и на собеседованиях.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
Java-разработчики, устали возиться с email-доставкой?
Забудьте о проблемах с SMTP, спамом и «письмах в никуда».
С HaskiMail вы отправляете транзакционные письма быстро, надёжно и без лишнего кода.
Почему Java-команды выбирают HaskiMail:
✔️ Готовая официальная библиотека для Java - подключи за 2 минуты
✔️ Отправка письма всего в 3 строки кода
✔️ Высочайшая доставляемость даже без выделенного IP
✔️ Транзакционные и маркетинговые письма по разным каналам (никакого влияния на критические уведомления!)
✔️ Поддержка, которая понимает Java и отвечает по делу
Интегрируйтесь сегодня и сосредоточьтесь на продукте, а не на почтовых серверах.
👉 Попробовать бесплатно!
Забудьте о проблемах с SMTP, спамом и «письмах в никуда».
С HaskiMail вы отправляете транзакционные письма быстро, надёжно и без лишнего кода.
Почему Java-команды выбирают HaskiMail:
✔️ Готовая официальная библиотека для Java - подключи за 2 минуты
✔️ Отправка письма всего в 3 строки кода
✔️ Высочайшая доставляемость даже без выделенного IP
✔️ Транзакционные и маркетинговые письма по разным каналам (никакого влияния на критические уведомления!)
✔️ Поддержка, которая понимает Java и отвечает по делу
Интегрируйтесь сегодня и сосредоточьтесь на продукте, а не на почтовых серверах.
👉 Попробовать бесплатно!
👎1