Java | Фишки и трюки
7.21K subscribers
182 photos
29 videos
6 files
40 links
Java: примеры кода, интересные фишки и полезные трюки

Купить рекламу: https://telega.in/c/java_tips_and_tricks

✍️По всем вопросам: @Pascal4eg
Download Telegram
⌨️ Создание RESTful API на Spring Boot

1️⃣ Настройка проекта

Создайте новый проект Spring Boot, добавив зависимости Spring Web и Lombok.

2️⃣ Создание модели User


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private String email;
}

Модель данных для пользователя с свойствами ID, именем и email.

3️⃣ Создание контроллера UserController


import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {
private final List<User> users = new ArrayList<>();

@GetMapping
public List<User> getAllUsers() {
return users; // Получение всех пользователей
}

@PostMapping
public User createUser(@RequestBody User user) {
users.add(user); // Создание нового пользователя
return user;
}
}

Контроллер, обрабатывающий запросы для получения и создания пользователей.

4️⃣ Примеры запросов

✔️ Получение всех пользователей:

Запрос:

GET /api/users

Возвращает список всех пользователей.

✔️ Создание нового пользователя:

Запрос:

POST /api/users
Content-Type: application/json

{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
}

Создаёт нового пользователя и возвращает его данные.

5️⃣ Тестирование API с Postman

Используйте Postman для отправки запросов и проверки работы вашего API. Вы можете получать данные, добавлять пользователей, обновлять и удалять их по аналогии с примерами выше.

#java #RESTfulAPI #SpringBoot
Please open Telegram to view this post
VIEW IN TELEGRAM
👍132🔥1🎉1
⌨️ Что такое Пул Потоков (Thread Pool)?

Пул потоков (Thread Pool) — это группа заранее созданных потоков, готовых к выполнению задач. Вместо создания нового потока для каждой задачи, пул повторно использует уже существующие потоки, что снижает нагрузку на систему и повышает производительность приложения.

📌 Основные виды пулов потоков:

1️⃣ Фиксированный Пул (Fixed Thread Pool):
- Создает заданное количество потоков. Если все потоки заняты, новые задачи ждут в очереди.


ExecutorService executor = Executors.newFixedThreadPool(5);


2️⃣ Пул с переменным количеством потоков (Cached Thread Pool):
- Создает новые потоки по мере необходимости и уничтожает неактивные потоки после определенного времени.


ExecutorService executor = Executors.newCachedThreadPool();


3️⃣ Планировщик (Scheduled Thread Pool):
- Позволяет выполнять задачи с задержкой или периодически.


ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);


🏷️ Используйте пулы потоков, чтобы упростить управление многопоточными задачами и улучшить производительность вашего приложения!

#java #ThreadPool
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
⌨️ Использование логов: Log4j и SLF4J

Логирование — важная часть программирования, позволяющая отслеживать поведение приложения, находить и устранять ошибки, а также анализировать производительность. В мире Java два наиболее популярных инструмента для логирования — Log4j и SLF4J. Разберем их, выясним, в чем их отличия, и как их эффективно использовать!

🛠 Log4j — это мощная библиотека логирования, создающая гибкий и настраиваемый механизм для записи отчетов о различных событиях.

Плюсы:
- Гибкая настройка: Вы можете четко настраивать уровни логирования, выводить логи в различные форматы и хранить их в файлах или базах данных.
- Аспектная ориентация: Легко создавать сложные правила логирования.

Пример использования Log4j:

1. Добавление зависимостейpom.xml):


<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>


2. Создание конфигурации (log4j.properties):


log4j.rootLogger=DEBUG, FILE

log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=application.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n


3. Пример кода:


import org.apache.log4j.Logger;

public class Log4jExample {
static Logger logger = Logger.getLogger(Log4jExample.class);

public static void main(String[] args) {
logger.info("Информационное сообщение");
logger.error("Ошибка!", new Exception("Пример исключения"));
}
}


📖 SLF4J (Simple Logging Facade for Java) — это абстракция для разных библиотек логирования, которая позволяет сменить библиотеку логирования без изменения кода.

Плюсы:
- Универсальность: Поддерживает различные реализации логирования, что позволяет быть гибким в выборе инструментов.
- Чистота кода: Позволяет более лаконично управлять логами.

Пример использования SLF4J:

1. Добавление зависимостейpom.xml):


<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</dependency>


2. Пример кода:


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4jExample {
private static final Logger logger = LoggerFactory.getLogger(Slf4jExample.class);

public static void main(String[] args) {
logger.info("Информационное сообщение с SLF4J");
logger.error("Ошибка!", new Exception("Пример исключения"));
}
}


🔄 Когда использовать?

- Log4j — когда вам нужен детальный контроль и настройка логирования. Хорошо подходит для сложных приложений, требующих многофункционального логирования.

- SLF4J — когда нужна гибкость и возможность переключаться между различными библиотеками логирования. Идеален для разработчиков, работающих с несколькими проектами.

💡 Итог: Используйте SLF4J для создания абстрактного логирования и Log4j в качестве конкретной реализации, чтобы не только создать гибкую, но и мощную систему логирования для вашего Java-приложения!

#java #Logging #Log4j #SLF4J
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍102
😁22🤣42👍1
⌨️ Использование Fixed Thread Pool

1️⃣ Создание пула потоков

Для начала нужно создать экземпляр ExecutorService, который будет представлять ваш пул потоков. В этом примере мы создадим фиксированный пул из 5 потоков:
ExecutorService executor = Executors.newFixedThreadPool(5);


2️⃣ Отправка задач для выполнения

После создания пула, вы можете отправлять ему задачи с помощью метода submit(). В качестве примера, давайте создадим несколько задач, которые будут выполняться параллельно:
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Задача " + taskId + " выполняется в: " + Thread.currentThread().getName());
// Имитация длительной задачи
try {
Thread.sleep(1000); // Задержка на 1 секунду
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Задача " + taskId + " завершена в: " + Thread.currentThread().getName());
});
}


3️⃣ Завершение работы пула

После того как все задачи были отправлены, важно завершить работу пула, чтобы освободить ресурсы:
executor.shutdown(); // Ждем завершения всех задач


В этом примере создается пул из 5 потоков, и на него отправляется 10 задач. Поскольку пул состоит из 5 потоков, одновременно будут выполняться не более 5 задач. Остальные задачи будут ожидать своей очереди. Это демонстрирует, как Thread Pool управляет ресурсами и оптимизирует обработку задач.

При использовании Thread Pool вы можете быть уверены, что ваше приложение будет работать более эффективно, избегая затрат на создание новых потоков и управляя нагрузкой на систему.

#java #FixedThreadPool
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71
public class Quest {
public static void main(String[] args) {
System.out.print(op1() + op2() * op3());
}

private static int op1() {
System.out.print(1);
return 1;
}
private static int op2() {
System.out.print(2);
return 2;
}
private static int op3() {
System.out.print(3);
return 3;
}
}


#java #quest
👍3👎21
Что выведет код?
Anonymous Quiz
49%
1237
30%
2317
15%
1239
5%
2319
🤯15👍8🎉1
⌨️Метапрограммирование: Использование Reflection для динамического изменения кода

Reflection — это механизм в Java, который позволяет программам анализировать и манипулировать объектами во время выполнения. С помощью рефлексии вы можете:

✔️ Получать информацию о классах, методах и полях. Это позволяет динамически исследовать структуры данных вашего приложения.

✔️ Создавать экземпляры классов: Вы можете создавать объекты, не зная их тип на этапе компиляции.

✔️ Вызывать методы динамически: Это дает возможность запускать методы объектов, основываясь на их именах, переданных в виде строк.

✔️ Изменять значения полей: Вы можете динамически изменять значения полей объектов, что может быть особенно полезно в контексте тестирования или сериализации.

Преимущества использования рефлексии:

✔️ Потенциал для создания более абстрактного кода: Вы можете реализовать паттерны проектирования, такие как Dependency Injection.

✔️ Упрощение работы с библиотеками и фреймворками: Многие популярные библиотеки, такие как Spring и Hibernate, активно используют рефлексию для создания и управления объектами.

В следующем посте мы рассмотрим конкретные примеры использования рефлексии на практике. Оставайтесь с нами! 🚀

#Java #Метапрограммирование #Reflection
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
⌨️ Пример реализации Dependency Injection с использованием Reflection

Продолжаем тему метапрограммирования и поговорим о том, как реализовать паттерн проектирования Dependency Injection (DI) с использованием рефлексии. DI позволяет нам разделить зависимости и упростить управление ими, что делает код более чистым и тестируемым.

Пример: Простой контейнер для Dependency Injection

В этом примере мы создадим простой контейнер, который будет автоматически связывать зависимости на основе аннотаций. Для этого нам понадобятся:

1. Аннотация @Inject для пометки полей, которые мы хотим внедрить.
2. Контейнер для обработки аннотаций и создания объектов.

Шаг 1: Создаем аннотацию


import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface Inject {}


Шаг 2: Создаем классы с зависимостями


class Service {
public void serve() {
System.out.println("Service is working!");
}
}

class Client {
@Inject
private Service service;

public void doSomething() {
service.serve();
}
}


Шаг 3: Реализуем контейнер для Dependency Injection


import java.lang.reflect.Field;

class DIContainer {
public static void inject(Object obj) {
Class<?> clazz = obj.getClass();

for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)) {
try {
field.setAccessible(true); // Делаем поле доступным
Object dependency = field.getType().getDeclaredConstructor().newInstance(); // Создаем экземпляр зависимости
field.set(obj, dependency); // Внедряем зависимость
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}


Шаг 4: Используем наш контейнер


public class Main {
public static void main(String[] args) {
Client client = new Client();
DIContainer.inject(client); // Внедряем зависимости

client.doSomething(); // Вывод: Service is working!
}
}


Как это работает?

1️⃣ Мы создаем аннотацию @Inject, чтобы пометить поля, которые должны быть внедрены.

2️⃣ В классе Client поле service помечено этой аннотацией.

3️⃣ Контейнер DIContainer проходит по полям класса, ищет аннотацию @Inject, и, если находит, создает объект зависимости и устанавливает его в поле.

4️⃣ Когда мы вызываем метод doSomething, объект Service успешно внедрен, и мы можем использовать его методы.

#Java #Метапрограммирование #DependencyInjection
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥31
public class Quest {
public static void main(String[] args) {
System.out.println(4_32l + 4_32l);
}
}
👍4👎2
Что выведет код?
Anonymous Quiz
29%
8642
35%
864
36%
<Ошибка компиляции>
3🎉1
🚀 Усовершенствования в области параллелизма: Project Loom

Project Loom — это инициатива в Java, которая вводит легковесные потоки (или корутины), делая асинхронное программирование более простым и понятным. Он позволяет разработчикам создавать и управлять огромным количеством потоков с минимальными затратами на ресурсы.

Почему это важно?
С использованием Project Loom вы сможете писать асинхронный код в синхронном стиле, что улучшает читаемость и упрощает отладку. Это значит меньше вложенных колбеков и легче управляемый код.

Как это работает?
Потоки в Project Loom называются "виртуальными", и вы можете создавать их так же просто, как обычные:


public class LoomExample {
public static void main(String[] args) {
// Создаем виртуальный поток
Thread.startVirtualThread(() -> {
System.out.println("Hello from a virtual thread!");
});

// Основной поток продолжает работу
System.out.println("Hello from the main thread!");
}
}


В этом примере мы создаем виртуальный поток, который выводит сообщение в консоль. Основной поток продолжает выполнять свою работу параллельно, что показывает, как просто можно организовать параллелизм без сложных конструкций.

Project Loom облегчает жизнь разработчикам, позволяя создавать многопоточные приложения проще и удобнее.
👍121
⌨️ Метод Stream.distinct()

Если у вас есть поток, который может содержать повторяющиеся элементы, используйте операцию distinct(), чтобы удалить их.


var list = Arrays.asList(1, 2, 3, 3, 4, 5, 5);
var distinctList = list.stream()
.distinct()
.collect(Collectors.toList());
// distinctList: [1, 2, 3, 4, 5]
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🚀 Реактивное программирование с помощью Project Reactor

Реактивное программирование — это новый подход к созданию асинхронных и масштабируемых приложений. Project Reactor — библиотека для Java, которая делает этот процесс простым и эффективным.

🔍 Что такое Project Reactor?

Project Reactor предоставляет инструменты для работы с потоками данных, основанные на спецификации Reactive Streams. Это дает возможность обрабатывать асинхронные события, используя:

1. Mono: асинхронный поток, который возвращает 0 или 1 элемент. Идеален для единичных значений.

2. Flux: поток, который может вернуть 0, 1 или много элементов. Отлично подходит для работы с коллекциями данных.

Преимущества Project Reactor:

🏎️ Высокая производительность: Неблокирующая модель усиливает эффективность использования ресурсов.

🛠️ Простой в обработке ошибок: Реактивные методы делают управление ошибками интуитивным.

📜 Читабельный код: Операторы позволяют писать более чистый и понятный код.
5
⌨️ Простой пример использования Project Reactor, который демонстрирует основы работы с Mono и Flux.


import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class ProjectReactorExample {
public static void main(String[] args) {
// Пример с Mono
Mono<String> monoExample = Mono.just("Hello, Reactor!");
monoExample
.map(String::toUpperCase) // Преобразуем строку в верхний регистр
.subscribe(System.out::println); // Подписываемся и выводим результат

// Пример с Flux
Flux<Integer> fluxExample = Flux.just(1, 2, 3, 4, 5);
fluxExample
.filter(num -> num % 2 == 0) // Фильтруем четные числа
.map(num -> num * num) // Возводим в квадрат
.subscribe(System.out::println); // Подписываемся и выводим результат
}
}


🔍 Что происходит в коде?

1. Mono:
- Создаем экземпляр Mono с помощью Mono.just(), передавая строку.
- Используем метод map(), чтобы преобразовать строку в верхний регистр.
- Подписываемся на Mono с помощью subscribe, который выводит результат.

2. Flux:
- Создаем экземпляр Flux с числовыми значениями от 1 до 5.
- Фильтруем четные числа с помощью filter().
- Применяем map(), чтобы возвести каждое четное число в квадрат.
- Подписываемся на Flux и выводим результат.
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍41
public class Quest {
public static final Quest INSTANCE = new Quest();
private final int yearsAgo;
private static final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);

private Quest() {
yearsAgo = CURRENT_YEAR - 2000;
}

public int yearsAgo() {
return yearsAgo;
}

public static void main(String[] args) {
System.out.println(INSTANCE.yearsAgo());
}
}
👍1
Что выведет код?
Anonymous Quiz
42%
24
16%
-2000
8%
0
33%
<Ошибка компиляции>
🎉3👍1
🌱 Spring SpEL (Spring Expression Language) — это мощный язык выражений, предоставляемый фреймворком Spring. Он используется для динамической обработки данных, управления конфигурацией и вычисления значений в runtime. SpEL позволяет обращаться к свойствам объектов, вызывать методы, работать с коллекциями, выполнять арифметические и логические операции, а также взаимодействовать с бинами Spring.

Основные возможности SpEL:

✔️ Обращение к свойствам: person.name

✔️Вызов методов: person.getName()

✔️ Работа с коллекциями: фильтрация и проекция (list.?[property > 10]).

✔️ Логические и арифметические операции: age > 18 && hasLicense

✔️ Доступ к бинам Spring: @beanName.method()

Простой пример:

import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

public class SpELExample {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();

// Пример вычисления простого выражения
String expression = "'Hello, Spring SpEL!'.toUpperCase()";
String result = parser.parseExpression(expression).getValue(String.class);

System.out.println(result); // Вывод: HELLO, SPRING SPEL!
}
}


Использование в аннотациях:

@Component
public class MyBean {
@Value("#{T(java.lang.Math).random() * 100}")
private double randomValue;

@Value("#{systemProperties['user.name']}")
private String userName;

public void printValues() {
System.out.println("Random Value: " + randomValue);
System.out.println("User Name: " + userName);
}
}


✔️ T(java.lang.Math).random() — вызов статического метода Math.random().

✔️ systemProperties['user.name'] — доступ к системным свойствам.

Использование с коллекциями:

import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

import java.util.Arrays;
import java.util.List;

public class CollectionExample {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// Фильтрация списка
List<Integer> filteredNumbers = (List<Integer>) parser.parseExpression(
"#numbers.?[#this > 2]").getValue(new StandardEvaluationContext(), numbers);

System.out.println(filteredNumbers); // Вывод: [3, 4, 5]
}
}


SpEL является удобным инструментом для внедрения динамического поведения и вычислений в приложениях Spring.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍93
public class Quest {
public static void main(String[] args) {
String s = null;
System.out.println(s instanceof String);
}
}
👍2