uk
Feedback
Java | Фишки и трюки

Java | Фишки и трюки

Відкрити в Telegram

Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg

Показати більше
6 822
Підписники
-224 години
-107 днів
-6130 день
Архів дописів
⌨️ Что такое перечисления (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();
        // Это пятница
    }
}

⌨️ Как ^, | и & работают с целочисленными операндами Пример:

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.

Изоляция рунета произошла быстрее, чем ты думал
Loading ██████████████] 99%
Роскомнадзору воспользовался карт-бланшем на блокировку, а «белые списки» сайтов внедрены уже во всех регионах. И гайки будут закручиваться только сильнее. Чтобы в одночасье не лишиться доступа к свободному Интернету, просто сохрани Only Hack. Тут профессиональный хакер делится фишками, с которыми доступ к глобальной сети у тебя будет даже в случае ядерного апокалипсиса. Не жди момента «Х». Перестрахуйся подпиской.

⌨️ Полезные стримы. Группировка Дан список людей с именем и городом проживания. Нужно сгруппировать их по городам.

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 #grouping

🔍 ТОП-5 ошибок на алгоритмической сессии Привет, на связи Таня Коровкина из ШОРТКАТ. Ментор по алгоритмам и backend-разработ
🔍 ТОП-5 ошибок на алгоритмической сессии Привет, на связи Таня Коровкина из ШОРТКАТ. Ментор по алгоритмам и backend-разработчик Каждый месяц тысячи разработчиков совершают одни и те же ошибки на алгоритмических интервью 🚩 И продолжают готовиться... не к тому. 6 июля(понедельник) в 19:00 (МСК) проведу вебинар и покажу, что на самом деле оценивает интервьюер и какие ошибки чаще всего приводят к отказу • дам практические советы, которые можно использовать уже на следующем собеседовании • расскажу про специфику российского BigTech 🤘 Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. О рекламодателе.

⌨️ Параллельные и последовательные потоки (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 #parallelStream

🔴 Завтра тестовое собеседование с Java-разработчиком 2 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседов
🔴 Завтра тестовое собеседование с Java-разработчиком 2 июля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика. Как это будет: 📂 Виктор Анохин, старший разработчик из WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Виктор будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Виктору Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. О рекламодателе.

⌨️ 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 #ForkJoinPool

30 июня в 18:00 начнется бесплатный вебинар «Почему Java-разработчику следует брать на вооружение Quarkus». В прямом эфире ра
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 (Мск) 👉Регистрация👈 #реклама О рекламодателе

⌨️ 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

👩‍💻 Как работает @Transactional в Spring: границы транзакций и типовые ошибки Приглашаем на открытый урок. 🗓 29 июня в 20:
👩‍💻 Как работает @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

⌨️ 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

Привет! hh team сделали тут на днях бота с простым тестовым заданием, но не успели оттестировать, потому что Олег ушёл в отпу
Привет! hh team сделали тут на днях бота с простым тестовым заданием, но не успели оттестировать, потому что Олег ушёл в отпуск. Олег, вернись, мы всё простим. Потестируйте, в общем, пжлст, по кнопке под постом ⚡ Задачка на три минуты — если справитесь, велкам в розыгрыш призов. 5 победителей: каждому подарим футболку, шопер и брелок. Итоги 30 июня в 12:00 мск, выберем рандомом. Погнали? 🚗 Начать #реклама 16+ О рекламодателе

🔄 Бесконечные потоки Интерфейс Stream имеет два статических метода для генерации бесконечных потоков: iterate() и generate()
🔄 Бесконечные потоки Интерфейс Stream имеет два статических метода для генерации бесконечных потоков: iterate() и generate(). iterate(final T seed, final UnaryOperator<T> f) возвращает бесконечный последовательный упорядоченный поток, созданный путем итеративного применения функции f к исходному элементу начального значения, создавая поток, состоящий из начального числа, f(начальное число), f(f(начальное число)) и т. д. generate(Supplier<? extends T> s) возвращает бесконечный последовательный неупорядоченный поток, в котором каждый элемент создается предоставленным поставщиком (Supplier). Это подходит для генерации константных потоков, потоков случайных элементов и т. д. 📌 При работе с бесконечными потоками, крайне важно вызвать метод limit() перед вызовом терминальной операции, иначе наша программа будет работать бесконечно.

⌨️ Как добавить элемент в середину массива? Есть несколько способов добавить элемент в середину массива. Однако, поскольку массивы имеют фиксированную длину, напрямую добавить элемент в существующий массив нельзя — нужно создавать новый массив с увеличенной длиной и копировать данные. Рассмотрим несколько способов: 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

🤖 Как создать B2B CRM с ИИ на Джеймикс и не потерять контроль над разработкой? ➡️ 2023 — попробуй ChatGPT ➡️ 2024 — генериру
🤖 Как создать B2B CRM с ИИ на Джеймикс и не потерять контроль над разработкой? ➡️ 2023 — попробуй ChatGPT ➡️ 2024 — генерируй код ➡️ 2025 — используй агентов ➡️ 2026 — пора разобраться, как встроить ИИ в управляемый процесс разработки 16 июня в 16:00 МСК — практический воркшоп от Джеймикс (Java-платформа с ИИ для разработки корпоративных систем), Kodacode и OpenIDE. Покажем, как пройти путь от постановки задачи до рабочего контура корпоративной CRM. Не в теории — в коде. Что разберём: 🔹 как сформировать спецификацию для разработки с ИИ 🔹 как удержать агента в рамках проекта 🔹 как создать модель данных, экраны и бизнес-логику 🔹 типичные ошибки агентного режима и как их исправлять 🔹 чем управляемая ИИ-разработка отличается от вайб-кодинга Заберёте с собой:готовый код open-source B2B CRM на Java со встроенным ИИ-ассистентом — можно сразу брать за основу в своих проектах. 👉 Регистрируйтесь #реклама О рекламодателе

⌨️ Выполнение команды в командной строке с выводом результата

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

🛠 От BPMN до контейнера: собираем Java-приложение с OpenBPM и Axiom JDK Приглашаем на вебинар, где пройдем практический путь
🛠 От BPMN до контейнера: собираем Java-приложение с OpenBPM и Axiom JDK Приглашаем на вебинар, где пройдем практический путь от выстраивания бизнес-логики до релиза в приложения безопасном enterprise-контуре. Покажем, как собрать Spring Boot-приложение в OpenIDE с плагином от OpenBPM: описать BPMN-схему, связать ее с Java-логикой, запустить на Axiom JDK и аккуратно упаковать все это в контейнеры. Отдельно обсудим ИИ в разработке (а куда сейчас без него?). Обещать «заменить команду с помощью Claude» не будем, но точно расскажем, как искусственный интеллект помогает оптимизировать рутину, сохранив контроль и зоны ответственности. 📅 16 июня, онлайн, 11:00. 👥 Спикеры: — Никита Щиенко, Tech Lead, OpenBPM — Максим Сафронов, Технологический консультант Axiom JDK Все подробности — на странице вебинара. И не забудьте зарегистрироваться! #реклама О рекламодателе

⌨️ Захват переменных в лямбда-выражениях Лямбда-выражения могут захватывать переменные из внешнего окружения, делая их доступными внутри лямбда-функции. При этом переменные могут быть: 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