Java | Фишки и трюки
Відкрити в Telegram
Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg Менеджер по рекламе: @shmyzna
Показати більше6 934
Підписники
-524 години
-187 днів
+1530 день
Триває завантаження даних...
Схожі канали
Хмара тегів
Вхідні та вихідні згадування
---
---
---
---
---
---
Залучення підписників
червень '26
червень '26
+94
в 0 каналах
травень '26
+128
в 10 каналах
Get PRO
квітень '26
+52
в 1 каналах
Get PRO
березень '26
+51
в 8 каналах
Get PRO
лютий '26
+42
в 3 каналах
Get PRO
січень '26
+38
в 0 каналах
Get PRO
грудень '25
+75
в 25 каналах
Get PRO
листопад '25
+108
в 11 каналах
Get PRO
жовтень '25
+50
в 0 каналах
Get PRO
вересень '25
+28
в 6 каналах
Get PRO
серпень '25
+187
в 24 каналах
Get PRO
липень '25
+156
в 16 каналах
Get PRO
червень '25
+169
в 29 каналах
Get PRO
травень '25
+221
в 32 каналах
Get PRO
квітень '25
+290
в 35 каналах
Get PRO
березень '25
+291
в 32 каналах
Get PRO
лютий '25
+1 295
в 114 каналах
Get PRO
січень '25
+292
в 14 каналах
Get PRO
грудень '24
+196
в 1 каналах
Get PRO
листопад '24
+302
в 21 каналах
Get PRO
жовтень '24
+439
в 9 каналах
Get PRO
вересень '24
+226
в 1 каналах
Get PRO
серпень '24
+281
в 3 каналах
Get PRO
липень '24
+462
в 16 каналах
Get PRO
червень '24
+229
в 1 каналах
Get PRO
травень '24
+395
в 9 каналах
Get PRO
квітень '24
+874
в 9 каналах
Get PRO
березень '24
+408
в 6 каналах
Get PRO
лютий '24
+339
в 7 каналах
Get PRO
січень '24
+330
в 5 каналах
Get PRO
грудень '23
+595
в 10 каналах
Get PRO
листопад '23
+663
в 12 каналах
Get PRO
жовтень '23
+656
в 8 каналах
Get PRO
вересень '23
+538
в 0 каналах
| Дата | Залучення підписників | Згадування | Канали | |
| 24 червня | +2 | |||
| 23 червня | +2 | |||
| 22 червня | +1 | |||
| 21 червня | +1 | |||
| 20 червня | +1 | |||
| 19 червня | +1 | |||
| 18 червня | 0 | |||
| 17 червня | +4 | |||
| 16 червня | +2 | |||
| 15 червня | +3 | |||
| 14 червня | +1 | |||
| 13 червня | +1 | |||
| 12 червня | +3 | |||
| 11 червня | 0 | |||
| 10 червня | +2 | |||
| 09 червня | 0 | |||
| 08 червня | +3 | |||
| 07 червня | +2 | |||
| 06 червня | +2 | |||
| 05 червня | +3 | |||
| 04 червня | +9 | |||
| 03 червня | +11 | |||
| 02 червня | +36 | |||
| 01 червня | +4 |
Дописи каналу
⌨️ Stream.reduce() vs Collectors.joining()
Когда требуется конкатенировать строки с использованием
Stream, можно выбрать один из двух методов: Stream.reduce() или Stream.collect(Collectors.joining()).
Пример с Stream.reduce():
List<String> list = List.of("Str1", "Str2", "Str3");
String result = list.stream().reduce("", (a, b) -> a + b);
System.out.println(result); // Str1Str2Str3
Пример с Collectors.joining():
List<String> list = List.of("Str1", "Str2", "Str3");
String result = list.stream().collect(Collectors.joining());
System.out.println(result); // Str1Str2Str3
Использование reduce() для конкатенации строк не является оптимальным с точки зрения производительности. При каждом вызове операции +, создается новая строка, так как строки в Java неизменяемы. Это приводит к увеличению нагрузки на память из-за создания множества промежуточных объектов.
В свою очередь, метод Collectors.joining() использует StringBuilder для сборки строк, что значительно эффективнее. Он избегает создания лишних объектов и снижает потребление памяти.
#java #Stream #reduce #joining| 2 | 👩💻 Как работает @Transactional в Spring: границы транзакций и типовые ошибки
Приглашаем на открытый урок.
🗓 29 июня в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework».
На занятии мы разберем:
✔️Что реально делает @Transactional в Spring
✔️Почему важны proxy и вызов метода через Spring Bean
✔️Как работают propagation-режимы на примере REQUIRED и REQUIRES_NEW
✔️Когда происходит rollback и почему checked exceptions не всегда откатывают транзакцию
✔️Типовые ошибки при работе с транзакциями в сервисном слое
Урок будет полезен Java/Kotlin-разработчикам, которые уже пишут приложения на Spring или начинают использовать Spring в реальных backend-проектах и хотят лучше понимать поведение транзакций.
🔗 Ссылка на регистрацию: https://otus.pw/TK9R/
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576 | 528 |
| 3 | ⌨️ POJO (Plain Old Java Object) — это простой Java-объект, не зависящий от каких-либо специфичных библиотек, фреймворков или технологий. Такой объект обычно содержит только поля (атрибуты) и методы доступа (геттеры и сеттеры), без дополнительной логики, аннотаций или наследования от специфических классов.
Пример POJO:
public class Person {
private String name;
private int age;
// Конструктор
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Геттеры и сеттеры
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
POJO используется для создания простых объектов без привязки к какой-либо специфической архитектуре или фреймворку. Например, в JPA объекты-сущности часто являются POJO, что позволяет их использовать независимо от платформы.
#java #pojo | 640 |
| 4 | Привет!
hh team сделали тут на днях бота с простым тестовым заданием, но не успели оттестировать, потому что Олег ушёл в отпуск. Олег, вернись, мы всё простим.
Потестируйте, в общем, пжлст, по кнопке под постом ⚡
Задачка на три минуты — если справитесь, велкам в розыгрыш призов.
5 победителей: каждому подарим футболку, шопер и брелок.
Итоги 30 июня в 12:00 мск, выберем рандомом.
Погнали? 🚗
Начать
#реклама 16+
О рекламодателе | 654 |
| 5 | 🔄 Бесконечные потоки
Интерфейс Stream имеет два статических метода для генерации бесконечных потоков: iterate() и generate().
iterate(final T seed, final UnaryOperator<T> f) возвращает бесконечный последовательный упорядоченный поток, созданный путем итеративного применения функции f к исходному элементу начального значения, создавая поток, состоящий из начального числа, f(начальное число), f(f(начальное число)) и т. д.
generate(Supplier<? extends T> s) возвращает бесконечный последовательный неупорядоченный поток, в котором каждый элемент создается предоставленным поставщиком (Supplier). Это подходит для генерации константных потоков, потоков случайных элементов и т. д.
📌 При работе с бесконечными потоками, крайне важно вызвать метод limit() перед вызовом терминальной операции, иначе наша программа будет работать бесконечно. | 878 |
| 6 | ⌨️ Как добавить элемент в середину массива?
Есть несколько способов добавить элемент в середину массива. Однако, поскольку массивы имеют фиксированную длину, напрямую добавить элемент в существующий массив нельзя — нужно создавать новый массив с увеличенной длиной и копировать данные. Рассмотрим несколько способов:
1️⃣ Копирование вручную
Суть в том что бы создать новый массив на 1 элемент больше оригинального и перенести элементы из старого, не забыв при этом вставить новый элемент.
int[] array = {1, 2, 4, 5};
int index = 2; // индекс, куда вставить новый элемент
int newElement = 3;
// Создаем новый массив на 1 больше
int[] newArray = new int[array.length + 1];
// Копируем элементы до позиции вставки
for (int i = 0; i < index; i++) {
newArray[i] = array[i];
}
// Вставляем новый элемент
newArray[index] = newElement;
// Копируем оставшиеся элементы
for (int i = index + 1; i < newArray.length; i++) {
newArray[i] = array[i - 1];
}
// Печатаем новый массив
System.out.println(Arrays.toString(newArray)); // [1, 2, 3, 4, 5]
2️⃣ Использование коллекций (например, ArrayList)
ArrayList динамический по размеру, и можно легко вставить элемент в любое место с помощью метода add(index, element).
Integer[] array = {1, 2, 4, 5};
int index = 2; // индекс, куда вставить новый элемент
int newElement = 3;
List<Integer> list = new ArrayList<>(Arrays.asList(array));
// Вставляем элемент
list.add(index, newElement);
// Создаем новый массив на 1 больше
Integer[] newArray = list.toArray(array);
// Печатаем новый массив
System.out.println(Arrays.toString(newArray)); // [1, 2, 3, 4, 5]
3️⃣ Использование метода System.arraycopy
Метод System.arraycopy позволяет эффективно копировать части массива.
int[] array = {1, 2, 4, 5};
int index = 2; // индекс, куда вставить новый элемент
int newElement = 3;
// Создаем новый массив на 1 больше
int[] newArray = new int[array.length + 1];
// Копируем элементы до позиции вставки
System.arraycopy(array, 0, newArray, 0, index);
// Вставляем новый элемент
newArray[index] = newElement;
// Копируем оставшиеся элементы
System.arraycopy(array, index, newArray, index + 1, array.length - index);
// Печатаем новый массив
System.out.println(Arrays.toString(newArray)); // [1, 2, 3, 4, 5]
#java #array | 1 018 |
| 7 | 🤖 Как создать B2B CRM с ИИ на Джеймикс и не потерять контроль над разработкой?
➡️ 2023 — попробуй ChatGPT
➡️ 2024 — генерируй код
➡️ 2025 — используй агентов
➡️ 2026 — пора разобраться, как встроить ИИ в управляемый процесс разработки
16 июня в 16:00 МСК — практический воркшоп от Джеймикс (Java-платформа с ИИ для разработки корпоративных систем), Kodacode и OpenIDE.
Покажем, как пройти путь от постановки задачи до рабочего контура корпоративной CRM. Не в теории — в коде.
Что разберём:
🔹 как сформировать спецификацию для разработки с ИИ
🔹 как удержать агента в рамках проекта
🔹 как создать модель данных, экраны и бизнес-логику
🔹 типичные ошибки агентного режима и как их исправлять
🔹 чем управляемая ИИ-разработка отличается от вайб-кодинга
Заберёте с собой:готовый код open-source B2B CRM на Java со встроенным ИИ-ассистентом — можно сразу брать за основу в своих проектах.
👉 Регистрируйтесь
#реклама
О рекламодателе | 473 |
| 8 | ⌨️ Выполнение команды в командной строке с выводом результата
public class CommandLine {
public static void main(String[] args) throws IOException {
Runtime rt = Runtime.getRuntime();
String[] commands = {"ping", "-c 5", "google.com"};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
}
}
Метод Runtime.getRuntime() возвращает объект, представляющий текущую среду выполнения Java. Этот объект позволяет запускать команды системы.
Метод exec() запускает системную команду и возвращает объект Process, который представляет запущенный процесс. Команда, которую нужно выполнить, передается как массив строк.
Далее получаем поток для чтения данных из стандартного вывода процесса, который был запущен и выводим на консоль. Так же поступаем и с потоком вывода ошибок.
Вывод:
Here is the standard output of the command:
PING google.com (173.194.222.138): 56 data bytes
64 bytes from 173.194.222.138: icmp_seq=0 ttl=60 time=39.479 ms
64 bytes from 173.194.222.138: icmp_seq=1 ttl=60 time=39.753 ms
64 bytes from 173.194.222.138: icmp_seq=2 ttl=60 time=47.982 ms
64 bytes from 173.194.222.138: icmp_seq=3 ttl=60 time=39.569 ms
64 bytes from 173.194.222.138: icmp_seq=4 ttl=60 time=39.850 ms
--- google.com ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 39.479/41.327/47.982/3.330 ms
Here is the standard error of the command (if any):
#java #Runtime #exec | 1 122 |
| 9 | 🛠 От BPMN до контейнера: собираем Java-приложение с OpenBPM и Axiom JDK
Приглашаем на вебинар, где пройдем практический путь от выстраивания бизнес-логики до релиза в приложения безопасном enterprise-контуре.
Покажем, как собрать Spring Boot-приложение в OpenIDE с плагином от OpenBPM: описать BPMN-схему, связать ее с Java-логикой, запустить на Axiom JDK и аккуратно упаковать все это в контейнеры.
Отдельно обсудим ИИ в разработке (а куда сейчас без него?). Обещать «заменить команду с помощью Claude» не будем, но точно расскажем, как искусственный интеллект помогает оптимизировать рутину, сохранив контроль и зоны ответственности.
📅 16 июня, онлайн, 11:00.
👥 Спикеры:
— Никита Щиенко, Tech Lead, OpenBPM
— Максим Сафронов, Технологический консультант Axiom JDK
Все подробности — на странице вебинара. И не забудьте зарегистрироваться!
#реклама
О рекламодателе | 494 |
| 10 | ⌨️ Захват переменных в лямбда-выражениях
Лямбда-выражения могут захватывать переменные из внешнего окружения, делая их доступными внутри лямбда-функции. При этом переменные могут быть:
1️⃣ Неизменяемыми (effectively final) – Переменная из внешнего контекста, используемая в лямбде, должна быть объявлена как final или фактически быть неизменяемой (то есть не изменяться после первого присваивания). Например:
int x = 10;
Runnable r = () -> System.out.println(x); // x захвачен в лямбде
2️⃣ Свободными от изменения в лямбде – Лямбда не может изменять захваченные переменные. Это ограничение гарантирует, что нет неоднозначного состояния, когда переменная изменяется из нескольких мест (например, из основного потока и из лямбда-функции одновременно).
3️⃣ Статическими или полями класса – В отличие от локальных переменных, статические поля класса или поля экземпляра могут свободно изменяться внутри лямбда-выражений, поскольку их значения хранятся в куче (heap) и доступны по ссылке.
Пример:
public class Main {
private static int staticVar = 20;
public static void main(String[] args) {
int localVar = 10;
Runnable r = () -> System.out.println(localVar + staticVar);
r.run();
}
}
В этом примере localVar захватывается, так как он effectively final, а staticVar доступен, так как это статическое поле.
#java #lambda #capturing | 1 034 |
| 11 | Решать технические задачи — самая простая часть работы в IT.
Сложности начинаются там, где нужно договариваться со смежниками, выстраивать процессы в хаосе и осознанно управлять карьерой.
В канале @ulshinblog Никита (руководитель разработки в Highload, 10+ лет в IT) разбирает эти темы через понятную логику и личный опыт:
📍 Как пройти секцию System Design? Пошаговый чек-лист от интервьюера;
📍 Как находить внутренние сайд-проекты, которые принесут пользу и бизнесу, и вашему карьерному росту;
📍 Защита от плохой обратной связи: как вежливо поставить на место коллегу с неконструктивным фидбеком;
📍 Инженерный конвейер самообучения: как перестать читать книги для галочки и внедрять знания в жизнь и карьеру;
📚 База 50+ авторских обзоров IT-литературы для сильного инженера: разработка, управление, архитектура, мышление.
👉 Присоединяйтесь | 514 |
| 12 | Java-приложение в Docker
В современном мире разработки программного обеспечения Docker становится важным инструментом, помогающим разрабатывать, тестировать и развертывать приложения в изолированной среде. Использование Docker с Java-приложениями позволяет значительно упростить процесс развертывания, гарантируя, что ваше приложение будет работать одинаково на всех средах.
Docker — это платформа для создания, развертывания и управления контейнерами. Контейнеры изолируют приложения и все их зависимости, что делает возможным запуск кода в любом окружении без конфликта с другими приложениями.
Шаг 1: Установка Docker
Перед тем как начать, убедитесь, что Docker установлен на вашем компьютере. Вы можете следовать [официальной документации](https://docs.docker.com/get-docker/) для установки на вашу операционную систему.
Шаг 2: Создание Java-приложения
Для примера создадим простое приложение. Предположим, у вас есть простая программа, которая выводит "Hello, World!".
Создайте файл HelloWorld.java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Скомпилируйте её с помощью:
javac HelloWorld.java
Шаг 3: Создание Dockerfile
Dockerfile — это текстовый файл, позволяющий автоматически собирать образ Docker. Создайте файл с именем Dockerfile в каталоге вашего проекта:
# Используем официальный образ OpenJDK
FROM openjdk:17-jdk-slim
# Устанавливаем рабочий каталог
WORKDIR /app
# Копируем скомпилированный класс в контейнер
COPY HelloWorld.class ./
# Определяем команду запуска
CMD ["java", "HelloWorld"]
Шаг 4: Сборка Docker-образа
Теперь создайте Docker-образ, используя следующую команду в каталоге вашего проекта:
docker build -t helloworld .
Эта команда соберет образ и назовет его helloworld.
Шаг 5: Запуск контейнера
Чтобы запустить контейнер, выполните команду:
docker run --rm helloworld
Вы должны увидеть вывод:
Hello, World!
Флаг --rm автоматически удаляет контейнер после его остановки.
#java #docker | 872 |
| 13 | 🔴 Завтра тестовое собеседование с Java-разработчиком
10 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Виктор Анохин, старший разработчик из WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Виктор будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Виктору
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе. | 617 |
| 14 | ☕️Text Blocks в Java: читаемые строки без \n и слёз
До Java 13 работа с многострочными строками была болью. JSON? HTML? SQL? Только через "\n" + и кучу экранирования.
Но с Text Blocks всё стало проще, понятнее и читаемо.
Сравни:
❌ До:
String html = "<html>\n" +
" <body>Hello</body>\n" +
"</html>";
✅ После (Text Block):
String html = """
<html>
<body>Hello</body>
</html>
""";
➡️ Стало чище, короче и как в оригинале. Это обычная String, просто оформленная красиво.
✔️ Преимущества Text Blocks:
1. 👍 Читаемость на уровне "как есть"
Код больше не превращается в кашу. Особенно полезно для:
SQL-запросов:
String query = """
SELECT id, name
FROM users
WHERE active = true
ORDER BY created_at DESC
""";
HTML/JSON шаблонов:
String json = """
{
"name": "Alice",
"role": "admin"
}
""";
2. 👍 Меньше экранирования
Забудь про \", \\n, \\t — теперь можно писать почти как в блокноте.
3. 👍 Автоматическое выравнивание
Java сама уберёт начальные отступы на основе самой "узкой" строки.
Пример:
String msg = """
Line 1
Line 2
Line 3
""";
➡️ Результат будет:
Line 1
Line 2
Line 3
4. 👍 Интеграция с .formatted()
Нельзя вставить переменные прямо в Text Block?
Используем .formatted() — коротко и читабельно:
String user = "Bob";
String template = """
{
"user": "%s",
"access": "granted"
}
""".formatted(user);
````
```java
String s = """
Hello""";
System.out.println(s.length()); // 6, а не 5 (есть \n)
3. 🟢 Нет интерполяции переменных
Нельзя писать так:
String name = "Eve";
String wrong = """
Hello, $name!
"""; // ❌ не сработает
Вместо этого:
String right = """
Hello, %s!
""".formatted(name);
🗣️ Запомни: Text Blocks делают строки в Java человечными. Это не просто сахар — это инструмент, чтобы твой код говорил с тобой на одном языке. Используй их для всего, что требует форматирования — и забудь про + "\n". | 1 020 |
| 15 | ⌨️ Java Concurrency API: Основные классы
Современные приложения все чаще требуют выполнения нескольких задач одновременно, и для этого Java предоставляет мощный инструмент — Concurrency API (набор классов и интерфейсов). Этот API позволяет разработчикам легко реализовывать многопоточность, управлять потоками и синхронизировать действия между ними, что значительно увеличивает производительность и отзывчивость приложений.
Основные классы:
1. Thread
- Класс для создания и управления потоками. Вы можете создать новый поток, реализовав интерфейс Runnable или расширив класс Thread.
2. Executor
- Интерфейс для управления потоками и выполнения задач. Позволяет абстрагироваться от управления потоками, сосредоточившись на логике приложения.
- ExecutorService: расширение Executor, управляющее жизненным циклом потоков.
3. Future
- Позволяет получать результаты из асинхронных задач. Используется в связке с ExecutorService для выполнения задач в фоновом режиме.
4. CountDownLatch
- Синхронизирует потоки, позволяя одному или нескольким потокам ждать завершения других потоков перед продолжением работы.
5. CyclicBarrier
- Используется для синхронизации группы потоков. Позволяет потоку ждать, пока все другие не достигнут определенной точки.
6. Semaphore
- Контролирует доступ к ресурсу, предоставляя определенное количество разрешений для потоков.
7. BlockingQueue
- Интерфейс, предоставляющий безопасный способ обмена данными между потоками при помощи очередей. Реализации включают ArrayBlockingQueue, LinkedBlockingQueue и другие.
#java #ConcurrencyAPI #Thread | 1 349 |
| 16 | Собрали подборку IT-каналов для тех, кто интересуется тестированием, разработкой, автотестами и карьерой в IT.
Внутри:
QA и AQA - практика, собеседования, рабочие заметки и разборы
Java и Python - задачи, тесты, полезные фишки и материалы для разработчиков
SQL и аналитика данных - запросы, работа с данными и прикладные разборы
Программирование и IT-карьера - каналы для тех, кто развивается в профессии и хочет лучше понимать рынок
Можно подписаться на всю подборку сразу или выбрать только те каналы, которые подходят под ваши цели.
Забрать папку | 589 |
| 17 | ⌨️ Desktop
Класс Desktop используется для взаимодействия с приложениями операционной системы, такими как веб-браузер, почтовый клиент, просмотрщик изображений и т.д. Этот класс входит в пакет java.awt и позволяет, например, открыть веб-ссылку в браузере или отправить письмо через почтовый клиент.
Основные возможности класса Desktop:
✔️ browse(URI uri) – открывает URI (например, веб-страницу) в браузере.
✔️ open(File file) – открывает файл в приложении, ассоциированном с его типом (например, текстовый файл в текстовом редакторе).
✔️ edit(File file) – открывает файл в режиме редактирования (если доступно).
✔️ mail(URI mailtoURI) – открывает почтовое приложение с указанным URI.
✔️ print(File file) – отправляет файл на печать.
Пример:
import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class DesktopExample {
public static void main(String[] args) throws IOException, URISyntaxException {
// Проверяем, поддерживает ли система класс Desktop
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
// Пример: Открытие веб-страницы
URI uri = new URI("http://www.google.com");
desktop.browse(uri);
} else {
System.out.println("Класс Desktop не поддерживается на этой системе.");
}
}
}
Проверка Desktop.isDesktopSupported() обязательна, так как класс может не поддерживаться на некоторых системах.
#java #Desktop | 1 471 |
| 18 | ⌨️ Почему Stream.parallel() может сделать код медленнее
Когда разработчики впервые видят:
list.parallelStream()
возникает мысль: О, бесплатная многопоточность 🚀
Но на практике parallelStream() очень часто:
❗ НЕ ускоряет код
❗ делает его медленнее
❗ а иногда ещё и ломает логику
📦 Как это работает
list.parallelStream()
.map(this::process)
.toList();
Java разбивает задачи между потоками через ForkJoinPool.commonPool().
🔥 Когда это реально помогает
✔️ CPU-heavy вычисления
✔️ большие объёмы данных
✔️ независимые операции
Например:
✅ обработка миллионов чисел
✅ сложные математические вычисления
✅ image processing
⚠️ Когда будет хуже
❌ Маленькие коллекции
List.of(1, 2, 3)
.parallelStream()
👉 накладные расходы на потоки будут больше пользы
❌ I/O операции
users.parallelStream()
.map(this::callApi)
👉 потоки начинают ждать сеть/БД
👉 ForkJoinPool забивается
❌ Общие mutable-данные
List<String> result = new ArrayList<>();
list.parallelStream()
.forEach(result::add);
💣 Race condition detected 🙂
❌ Неочевидный порядок
parallelStream().forEach(System.out::println);
Порядок вывода будет случайным.
🧠 Самая скрытая проблема
parallelStream() использует ОБЩИЙ pool потоков.
То есть:
▸ твой код
▸ библиотека
▸ другой модуль приложения
могут конкурировать за одни и те же потоки.
👉 Особенно весело в backend-приложениях.
🚀 Иногда обычный stream быстрее
Почему?
Потому что parallel:
▸ делит задачи
▸ синхронизирует результаты
▸ координирует потоки
Это тоже стоит времени.
✅ Хорошее правило
Используй parallelStream() только если:
▸ операция тяжёлая
▸ данных много
▸ нет shared mutable state
▸ ты реально измерил performance | 1 586 |
| 19 | ⌨️ EnumMap — это реализация Map, которая использует в качестве ключей исключительно Enum.
Внутренне EnumMap использует массив для хранения значений, где индекс массива соответствует порядковому номеру (ordinal()) элемента перечисления. Это делает его быстрее, чем хэш-таблицы (HashMap) и более экономным по памяти.
EnumMap хранит ключи в порядке их объявления в перечислении, что отличает его от большинства других Map (кроме LinkedHashMap).
Так как ключи строго ограничены перечислением, это снижает вероятность ошибок при разработке.
🔍 Пример:
import java.util.EnumMap;
enum Action {
START, STOP, PAUSE
}
public class EnumMapExample {
public static void main(String[] args) {
EnumMap<Action, Runnable> actionMap = new EnumMap<>(Action.class);
// Определяем поведение для каждого значения Enum
actionMap.put(Action.START, () -> System.out.println("Starting the process..."));
actionMap.put(Action.STOP, () -> System.out.println("Stopping the process..."));
actionMap.put(Action.PAUSE, () -> System.out.println("Pausing the process..."));
// Пример вызова
Action currentAction = Action.START;
actionMap.get(currentAction).run();
}
}
#Java #EnumMap | 1 586 |
| 20 | 👨👨👨👨👨👨👨👨👨👨
Каналы с Junior IT вакансиями
и стажировками
Подписывайся и забирай свой оффер 🤘
1. Стажировки и вакансии по России и миру
2. IT вакансии по СНГ
3. IT стажировки по СНГ
4. ИИ-ассистент для автооткликов
5. IT стажировки и волонтерства
6. IT стажировки в топовых компаниях мира
7. Удалённые IT вакансии и стажировки
8. Python вакансии и стажировки
9. БИГТЕХ вакансии и стажировки
10. Design вакансии и стажировки
11. QA вакансии и стажировки
12. Junior вакансии и стажировки
13. Frontend вакансии и вопросы собесов
14. Вакансии и стажировки для аналитиков
15. Вакансии в русских стартапах за границей
16. Вакансии и стажировки для DevOps
17. Вакансии, которых нет на ХХ.РУ | 0 |
Вже доступно! Дослідження Telegram за 2025 — головні інсайти року 
