Java | Фишки и трюки
الذهاب إلى القناة على Telegram
Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg
إظهار المزيد6 822
المشتركون
-224 ساعات
-107 أيام
-6130 أيام
أرشيف المشاركات
6 822
⌨️ Что такое перечисления (enum)?
Перечисления представляют набор логически связанных констант. Нужны для ограничения области допустимых значений: например, времена года, дни недели.
Перечисление фактически представляет новый класс, поэтому мы можем определить переменную данного типа и использовать ее.
Перечисления, как и обычные классы, могут определять конструкторы, поля и методы.
Следует отметить, что конструктор по умолчанию приватный.
Преимуществом Еnum перед обычными константами является возможность проверки типа данных.
К недостаткам относится невозможность применения операторов >, <, >=, <=, а так же большее потребление памяти по сравнению с обычными константами.
Встроенные методы:
- ordinal() возвращает порядковый номер определенной константы (нумерация начинается с 0)
- values() возвращает массив всех констант перечисления
public enum Day {
MONDAY("понедельник"),
TUESDAY("вторник"),
WEDNESDAY("среда"),
THURSDAY("четверг"),
FRIDAY("пятница"),
SATURDAY("суббота"),
SUNDAY("воскресенье");
Day(String value) {
this.value = value;
}
String value;
public String getValue() {
return value;
}
}
public class EnumClass {
public static void main(String[] args) {
System.out.println(message(Day.FRIDAY));
}
public static String message(Day day) {
return "Это " + day.getValue();
// Это пятница
}
}6 822
⚡️ Айтишник из «VISION» скупил курсы айти школ и выложил гигабайты материалов к себе
Каждый найдет что-то по душе:
1202 ГБ — Python
1811 ГБ — Frontend
1100 ГБ — C / C++ / C#
804 ГБ — Java
411 ГБ — SQL & БД
309 ГБ — DevOps
998 ГБ — ИБ & Хакинг
773 ГБ — Kotlin / Swift
189 ГБ — PHP
201 ГБ — GoLang
170 ГБ — Rust
167 ГБ — QA / Тестирование
310 ГБ — 1C + Лицензии
495 ГБ — Машинное обучение
704 ГБ — Аналитика Данных
991 ГБ — Дизайн
Материалы в закрепе, постоянно пополняются👆🏻
6 822
⌨️ Как ^, | и & работают с целочисленными операндами
Пример:
int a = 3 & 5;
int b = 3 | 5;
int c = 3 ^ 5;
System.out.println(a); // 1
System.out.println(b); // 7
System.out.println(c); // 6
Чтобы думать как Java, нужно:
✅ Перевести значения обоих операндов в двоичную систему счисления.
✅ Расположить результаты перевода друг под другом.
✅ Сравнять в них число разрядов (дополнить лидирующими нулями).
✅ Применить к битам из каждого столбца оператор (&, | или ^).
✅ Записать результат каждой операции ниже в том же столбце.
✅ Перевести итог в десятичную форму.
Потренеруемся на примере 3 & 5:
Число 3 в двоичной системе счисления имеет вид 11, а число 5 — 101.
Так как у числа 5 три разряда в двоичной системе, а у числа 3 — всего два, добавим лидирующий ноль к числу 3 в двоичной системе и получим 011.
Берём цифры из обоих чисел и применяем к ним попарно оператор & (AND):
011 &&& 101 === 001Получаем число 001. В десятичной записи ему соответствует число 1. Поэтому операция 3 & 5 и возвращает в результате 1.
6 822
Изоляция рунета произошла быстрее, чем ты думал
Loading … ██████████████] 99%Роскомнадзору воспользовался карт-бланшем на блокировку, а «белые списки» сайтов внедрены уже во всех регионах. И гайки будут закручиваться только сильнее. Чтобы в одночасье не лишиться доступа к свободному Интернету, просто сохрани Only Hack. Тут профессиональный хакер делится фишками, с которыми доступ к глобальной сети у тебя будет даже в случае ядерного апокалипсиса. Не жди момента «Х». Перестрахуйся подпиской.
6 822
⌨️ Полезные стримы. Группировка
Дан список людей с именем и городом проживания. Нужно сгруппировать их по городам.
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
record Person(String name, String city) {}
public class StreamExample {
public static void main(String[] args) {
List<Person> people = List.of(
new Person("Alice", "New York"),
new Person("Bob", "Los Angeles"),
new Person("Charlie", "New York"),
new Person("David", "Los Angeles"),
new Person("Edward", "San Francisco")
);
Map<String, List<Person>> peopleByCity = people.stream()
.collect(Collectors.groupingBy(Person::city));
peopleByCity.forEach((city, peopleInCity) -> {
System.out.println(city + ": " + peopleInCity.stream()
.map(Person::name)
.collect(Collectors.joining(", ")));
});
// Вывод:
// San Francisco: Edward
// New York: Alice, Charlie
// Los Angeles: Bob, David
}
}
#java #stream #grouping6 822
🔍 ТОП-5 ошибок на алгоритмической сессии
Привет, на связи Таня Коровкина из ШОРТКАТ. Ментор по алгоритмам и backend-разработчик
Каждый месяц тысячи разработчиков совершают одни и те же ошибки на алгоритмических интервью 🚩
И продолжают готовиться... не к тому.
6 июля(понедельник) в 19:00 (МСК) проведу вебинар и покажу, что на самом деле оценивает интервьюер и какие ошибки чаще всего приводят к отказу
• дам практические советы, которые можно использовать уже на следующем собеседовании
• расскажу про специфику российского BigTech
🤘 Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
6 822
⌨️ Параллельные и последовательные потоки (Stream)
Последовательные потоки (Sequential Streams)
✔️ Обрабатывают элементы последовательно, один за другим, на одном потоке, следовательно производительность ограничена возможностями одного ядра процессора.
✔️ Используют основной поток программы (main thread) для выполнения операций.
✔️ Метод stream() создаёт последовательный поток.
Пример последовательного потока:
List<String> list = List.of("Hello ", "w", "o", "r", "l", "d!");
list.stream().forEach(System.out::print);
// Hello world!
Параллельные потоки (Parallel Streams)
✔️ Обрабатывают элементы параллельно, распределяя их между несколькими потоками (threads), что позволяет использовать многопоточность.
✔️ Используют ForkJoinPool для распределения задач между потоками.
✔️ Эффективны для больших наборов данных, поскольку могут улучшить производительность на многоядерных процессорах.
✔️ Параллельный поток можно создать, вызвав метод parallelStream() или применив метод parallel() к уже существующему потоку.
Пример параллельного потока:
List<String> list = List.of("Hello ", "w", "o", "r", "l", "d!");
list.parallelStream().forEach(System.out::print);
// rlHello d!wo
#java #Stream #parallelStream6 822
🔴 Завтра тестовое собеседование с Java-разработчиком
2 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Виктор Анохин, старший разработчик из WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Виктор будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Виктору
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
6 822
⌨️ ForkJoinPool — это специальная реализация пула потоков, предназначенная для выполнения параллельных задач с использованием алгоритма разделяй и властвуй (divide and conquer). Этот пул потоков был представлен в Java 7 как часть библиотеки
java.util.concurrent.
Использует подход "разделяй и властвуй", где задача разбивается на подзадачи до тех пор, пока они не станут достаточно маленькими для последовательного решения. Для этого используются классы RecursiveTask<V> (возвращает результат) и RecursiveAction (без результата).
ForkJoinPool динамически управляет количеством потоков, при необходимости создавая новые. Обычно это количество соответствует числу процессоров, доступных в системе.
Использует технику work-stealing, где потоки, завершившие свои задачи, могут "красть" задачи у других потоков, чтобы эффективно использовать ресурсы процессора.
ForkJoinPool обладает высокой производительностью для задач, которые можно разбить на независимые подзадачи.
Основные методы:
invoke(): синхронно запускает задачу и ждет её завершения.
submit(): запускает задачу асинхронно.
execute(): также запускает задачу асинхронно, но не возвращает результат.
Пример использования:
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class SumTask extends RecursiveTask<Integer> {
private final int[] array;
private final int start, end;
private final int threshold = 10;
public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= threshold) {
// Базовый случай: небольшая задача
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
// Разделяем задачу
int mid = (start + end) / 2;
SumTask leftTask = new SumTask(array, start, mid);
SumTask rightTask = new SumTask(array, mid, end);
leftTask.fork(); // Асинхронно запускаем левую подзадачу
int rightResult = rightTask.compute(); // Синхронно вычисляем правую подзадачу
int leftResult = leftTask.join(); // Ждем завершения левой подзадачи
return leftResult + rightResult;
}
}
}
public class ForkJoinExample {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
SumTask task = new SumTask(array, 0, array.length);
int result = pool.invoke(task);
System.out.println("Сумма: " + result);
}
}
Этот код создает задачу для суммирования массива, разбивая его на подзадачи.
#java #ForkJoinPool6 822
30 июня в 18:00 начнется бесплатный вебинар «Почему Java-разработчику следует брать на вооружение Quarkus». В прямом эфире рассмотрим ключевые преимущества Quarkus перед Spring Boot: родную сборку (миллисекундный запуск), малое потребление памяти и удобство разработки.
Содержание:
✅Проблема долгого запуска и высокого потребления памяти в Spring Boot.
✅Что такое Quarkus? Окружающая среда расширений, родная сборка (GraalVM).
✅Живой код: создание REST-сервиса на Spring Boot и на Quarkus (сравнение).
✅Измерение времени запуска и потребления памяти.
✅Как родная сборка ускоряет размещение в Kubernetes и снижает затраты.
✅Настоящий случай из практики автора (обработка 1 000 tps).
✅Как продолжить изучение: курс QRK-001 «Quarkus: разработка микросервисов на Java или Kotlin».
👨🎓Спикер: Чвилёв Константин, эксперт в области разработки ПО
🗓️Когда: 30 июня, 18:00–19:00 (Мск)
👉Регистрация👈
#реклама
О рекламодателе
6 822
⌨️ 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 #joining6 822
👩💻 Как работает @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
6 822
⌨️ 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 #pojo6 822
Привет!
hh team сделали тут на днях бота с простым тестовым заданием, но не успели оттестировать, потому что Олег ушёл в отпуск. Олег, вернись, мы всё простим.
Потестируйте, в общем, пжлст, по кнопке под постом ⚡
Задачка на три минуты — если справитесь, велкам в розыгрыш призов.
5 победителей: каждому подарим футболку, шопер и брелок.
Итоги 30 июня в 12:00 мск, выберем рандомом.
Погнали? 🚗
Начать
#реклама 16+
О рекламодателе
6 822
🔄 Бесконечные потоки
Интерфейс Stream имеет два статических метода для генерации бесконечных потоков:
iterate() и generate().
iterate(final T seed, final UnaryOperator<T> f) возвращает бесконечный последовательный упорядоченный поток, созданный путем итеративного применения функции f к исходному элементу начального значения, создавая поток, состоящий из начального числа, f(начальное число), f(f(начальное число)) и т. д.
generate(Supplier<? extends T> s) возвращает бесконечный последовательный неупорядоченный поток, в котором каждый элемент создается предоставленным поставщиком (Supplier). Это подходит для генерации константных потоков, потоков случайных элементов и т. д.
📌 При работе с бесконечными потоками, крайне важно вызвать метод limit() перед вызовом терминальной операции, иначе наша программа будет работать бесконечно.6 822
⌨️ Как добавить элемент в середину массива?
Есть несколько способов добавить элемент в середину массива. Однако, поскольку массивы имеют фиксированную длину, напрямую добавить элемент в существующий массив нельзя — нужно создавать новый массив с увеличенной длиной и копировать данные. Рассмотрим несколько способов:
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 #array6 822
🤖 Как создать B2B CRM с ИИ на Джеймикс и не потерять контроль над разработкой?
➡️ 2023 — попробуй ChatGPT
➡️ 2024 — генерируй код
➡️ 2025 — используй агентов
➡️ 2026 — пора разобраться, как встроить ИИ в управляемый процесс разработки
16 июня в 16:00 МСК — практический воркшоп от Джеймикс (Java-платформа с ИИ для разработки корпоративных систем), Kodacode и OpenIDE.
Покажем, как пройти путь от постановки задачи до рабочего контура корпоративной CRM. Не в теории — в коде.
Что разберём:
🔹 как сформировать спецификацию для разработки с ИИ
🔹 как удержать агента в рамках проекта
🔹 как создать модель данных, экраны и бизнес-логику
🔹 типичные ошибки агентного режима и как их исправлять
🔹 чем управляемая ИИ-разработка отличается от вайб-кодинга
Заберёте с собой:готовый код open-source B2B CRM на Java со встроенным ИИ-ассистентом — можно сразу брать за основу в своих проектах.
👉 Регистрируйтесь
#реклама
О рекламодателе
6 822
⌨️ Выполнение команды в командной строке с выводом результата
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
6 822
🛠 От BPMN до контейнера: собираем Java-приложение с OpenBPM и Axiom JDK
Приглашаем на вебинар, где пройдем практический путь от выстраивания бизнес-логики до релиза в приложения безопасном enterprise-контуре.
Покажем, как собрать Spring Boot-приложение в OpenIDE с плагином от OpenBPM: описать BPMN-схему, связать ее с Java-логикой, запустить на Axiom JDK и аккуратно упаковать все это в контейнеры.
Отдельно обсудим ИИ в разработке (а куда сейчас без него?). Обещать «заменить команду с помощью Claude» не будем, но точно расскажем, как искусственный интеллект помогает оптимизировать рутину, сохранив контроль и зоны ответственности.
📅 16 июня, онлайн, 11:00.
👥 Спикеры:
— Никита Щиенко, Tech Lead, OpenBPM
— Максим Сафронов, Технологический консультант Axiom JDK
Все подробности — на странице вебинара. И не забудьте зарегистрироваться!
#реклама
О рекламодателе
6 822
⌨️ Захват переменных в лямбда-выражениях
Лямбда-выражения могут захватывать переменные из внешнего окружения, делая их доступными внутри лямбда-функции. При этом переменные могут быть:
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