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

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

✍️По всем вопросам: @Pascal4eg
Download Telegram
public class Quest {
public static void main(String[] args) {
int a = 5;
int b = 10;
int result = multiply(a, b);
System.out.println(result);
}

public static int multiply(int x, int y) {
if (y == 0) {
return 0;
} else {
return x + multiply(x, y - 1);
}
}
}

#java #quest
4
Что выведет код?
Anonymous Quiz
54%
50
11%
5
3%
10
33%
Бесконечная рекурсия
🎉6🌚4🫡1
public class Test {

public static int VAL;

{
VAL = 5;
}

public Test() {
VAL = 10;
}

public static void print() {
System.out.println(VAL);
}

}

public class Quest {
public static void main(String[] args) {
Test.print();
}
}


#java #quest
5
Что выведет код?
Anonymous Quiz
12%
0
35%
5
24%
10
29%
<ошибка компиляции>
🎉8
🌱 Spring Cloud Config — это проект в экосистеме Spring, который предоставляет сервер и клиент для централизованного управления конфигурацией в распределённых системах. Основная идея Spring Cloud Config — это вынесение конфигурационных файлов из приложений в единое место (например, репозиторий Git), чтобы облегчить управление конфигурацией для различных сервисов в микросервисной архитектуре.

Основные компоненты

✔️ Config Server — сервер, который хранит конфигурации (обычно в Git) и раздает их микросервисам.

✔️ Config Client — клиент в микросервисах, который получает конфигурации от Config Server.


Возможности

✔️ Централизация конфигураций всех сервисов.

✔️ Поддержка версионирования конфигураций (например, через Git).

✔️ Динамическое обновление конфигураций без перезапуска приложений с помощью Spring Cloud Bus.

✔️ Поддержка различных сред и профилей (dev, prod и т.д.).


Пример настройки Config Server:

spring:
cloud:
config:
server:
git:
uri: https://github.com/your-repo/config-repo


Пример настройки Config Client:

spring:
cloud:
config:
uri: http://localhost:8888
profile: dev


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

Недостатки: важен контроль за доступом и стабильностью Config Server.

#java #Spring #Cloud #Config
Please open Telegram to view this post
VIEW IN TELEGRAM
👍153🔥1
⌨️ События жизненного цикла объекта JPA

При работе с JPA есть несколько событий, о которых мы можем получать уведомления в течение жизненного цикла объекта.

JPA определяет семь событий жизненного цикла:

@PrePersist - перед тем, как вызывается persist для нового объекта

@PostPersist - после того, как вызывается persist для нового объекта

@PreRemove - прежде чем сущность будет удалена

@PostRemove - после удаления объекта

@PreUpdate - перед операцией обновления

@PostUpdate - после обновления сущности

@PostLoad - после загрузки объекта

Итак, если мы создаем новую сущность и вызываем метод сохранения нашего репозитория, вызывается наш метод, аннотированный @PrePersist, затем запись вставляется в базу данных и, наконец, вызывается наш метод @PostPersist. Если мы используем @GeneratedValue для автоматической генерации наших первичных ключей, мы можем ожидать, что этот ключ будет доступен в методе @PostPersist.

Для операций @PostPersist, @PostRemove и @PostUpdate в документации упоминается, что эти события могут произойти сразу после выполнения операции или в конце транзакции.

Следует отметить, что обратный вызов @PreUpdate вызывается только в том случае, если данные действительно изменяются, то есть если необходимо выполнить фактический оператор обновления SQL. Обратный вызов @PostUpdate вызывается независимо от того, действительно ли что-то изменилось.

Если какой-либо из наших обратных вызовов для сохранения или удаления объекта выдаст исключение, транзакция будет отменена.


@Entity
public class User {
private static Log log = LogFactory.getLog(User.class);

@Id
@GeneratedValue
private int id;

private String userName;
private String firstName;
private String lastName;
@Transient
private String fullName;

// getter and setter

@PrePersist
public void logNewUserAttempt() {
log.info("Attempting to add new user with username: " + userName);
}

@PostPersist
public void logNewUserAdded() {
log.info("Added user '" + userName + "' with ID: " + id);
}

@PreRemove
public void logUserRemovalAttempt() {
log.info("Attempting to delete user: " + userName);
}

@PostRemove
public void logUserRemoval() {
log.info("Deleted user: " + userName);
}

@PreUpdate
public void logUserUpdateAttempt() {
log.info("Attempting to update user: " + userName);
}

@PostUpdate
public void logUserUpdate() {
log.info("Updated user: " + userName);
}

@PostLoad
public void logUserLoad() {
fullName = firstName + " " + lastName;
}
}


#java #Entity #Lifecycle
Please open Telegram to view this post
VIEW IN TELEGRAM
👍134🔥1
⌨️ Jasypt (Java Simplified Encryption) — это библиотека для шифрования и защиты конфиденциальных данных в Java-приложениях. Она упрощает процесс шифрования и дешифрования данных, обеспечивая простой и интуитивно понятный API. Jasypt особенно полезен для шифрования конфигурационных файлов (например, паролей для баз данных), чувствительной информации в базах данных и других данных, требующих защиты.

Подключение зависимости:

<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.3</version>
</dependency>


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

String myEncryptionPassword = "mySuperSecretPassword";
String secretData = "secret data";

AES256TextEncryptor textEncryptor = new AES256TextEncryptor();
textEncryptor.setPassword(myEncryptionPassword);
String myEncryptedText = textEncryptor.encrypt(secretData);
System.out.println(myEncryptedText);
// DpMHE0Yy+6Ctlyx5lchU8j50Y2TRlGSOjHwIqAroxvmgq0VMijs/y8GkR9vcF1Pg

String plainText = textEncryptor.decrypt(myEncryptedText);
System.out.println(plainText); // secret data



Применение в Spring Boot

Для интеграции с Spring Boot Jasypt позволяет зашифровать чувствительные параметры конфигурации. Например, конфигурация для базы данных может быть записана так:

spring:
datasource:
url: ENC(encrypted-url)
username: ENC(encrypted-username)
password: ENC(encrypted-password)


Затем Jasypt автоматически расшифровывает эти значения при запуске приложения.

#java #Jasypt #cryptography
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍133
⌨️ Как добавить элемент в середину массива?

Есть несколько способов добавить элемент в середину массива. Однако, поскольку массивы имеют фиксированную длину, напрямую добавить элемент в существующий массив нельзя — нужно создавать новый массив с увеличенной длиной и копировать данные. Рассмотрим несколько способов:

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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍113👎2
public class Quest {
public static void main(String[] args) {
final String pig = "length: 10";
final String dog = "length: " + pig.length();

System.out.println("Animals are equal: " + pig == dog);
}
}

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


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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍93
⌨️ Пакетное выполнение запросов — это техника, которая позволяет выполнять несколько SQL-запросов в одной транзакции, что помогает оптимизировать производительность и уменьшить накладные расходы на соединение с базой данных. Основные методы для работы с пакетами запросов — это addBatch() и executeBatch(), которые являются частью интерфейса Statement (а также PreparedStatement и CallableStatement).

Метод addBatch() добавляет SQL-запрос (или его параметризованную версию в случае с PreparedStatement) в пакет запросов для последующего выполнения. Каждый вызов этого метода добавляет один SQL-запрос в очередь пакета.

Метод executeBatch() выполняет все запросы, добавленные в пакет.

Пример:

Class.forName("oracle.jdbc.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "username", "password");
Statement s = con.createStatement();

String sql1 = "CREATE TABLE STUDENT(STUDENTID VARCHAR2(10) PRIMARY KEY,NAME VARCHAR2(20),DEPARTMENT VARCHAR2(10))";
String sql2 = "INSERT INTO STUDENT VALUES('S101','JEAN','CSE')";
String sql3 = "INSERT INTO STUDENT VALUES('S102','ANA','CSE')";
String sql4 = "INSERT INTO STUDENT VALUES('S103','ROBERT','ECE')";

s.addBatch(sql1);
s.addBatch(sql2);
s.addBatch(sql3);
s.addBatch(sql4);

s.executeBatch();
con.commit();
con.close();


#java #addBatch #executeBatch
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍1
public class Quest {
public static void main(String[] args) {
System.out.println(isEqual(1, 1));
}

private static boolean isEqual(int i, int j) {
return (i == j) ? null : false;
}
}


#java #quest
4
Что выведет код?
Anonymous Quiz
4%
0
46%
null
12%
false
38%
<NullPointerExeption>
🖕6👍5🎉1
👻9🤣7😭61
public class Quest {
private final String name;

Quest(String name) {
this.name = name;
}

private String name() {
return name;
}

private void reproduce() {
new Quest("reproduce") {
void printName() {
System.out.println(name());
}
}.printName();
}

public static void main(String[] args) {
new Quest("main").reproduce();
}
}


#java #quest
3
Что выведет код?
Anonymous Quiz
28%
reproduce
19%
main
53%
<Ошибка компиляции>
🤯81🎉1
⌨️ Optional это полезная фишка языка, которая помогает работать с возможными null значениями, избегая проблем с NullPointerException.

Optional оборачивает значение, которое может быть либо пустым, либо присутствующим, и предоставляет методы для работы с этим значением безопасным способом.

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

Optional<String> name = Optional.ofNullable(getUserName());
name.ifPresent(n -> System.out.println("Имя пользователя: " + n));


Если значение есть, оно выводится на экран. Если значение null, программа просто пропустит это место, и не возникнет исключения. Также можно задать значение по умолчанию:

String defaultName = name.orElse("Гость");
System.out.println(defaultName);


Это делает код более устойчивым к ошибкам и улучшает его читаемость.

#java #Optional
Please open Telegram to view this post
VIEW IN TELEGRAM
👍123
⌨️ Ещё одна мощная фишка Java — это try-with-resources, которая значительно упрощает работу с ресурсами (например, файлами или сетевыми соединениями) и автоматически закрывает их после использования.

Обычно ресурсы, такие как файлы или потоки, нужно явно закрывать, чтобы избежать утечек. Но с помощью конструкции try-with-resources Java автоматически закроет ресурсы, когда они больше не нужны, даже если возникнет исключение.

Пример работы с файлом:

try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}


В этом коде BufferedReader автоматически закроется после выполнения блока try, что исключает риск утечки ресурсов. Эта конструкция делает код более чистым и безопасным.

#java #tryWithResources
Please open Telegram to view this post
VIEW IN TELEGRAM
👍63👏1
⌨️ Pattern Matching для instanceof

Начиная с Java 16, проверка типов с помощью instanceof стала гораздо удобнее благодаря Pattern Matching. Раньше, после проверки объекта на принадлежность к определённому классу, нужно было выполнять явное приведение типа. Теперь это можно сделать в одной строке.

Пример до Java 16:

if (obj instanceof String) {
String str = (String) obj;
System.out.println(str.length());
}


Пример с Pattern Matching:

if (obj instanceof String str) {
System.out.println(str.length());
}


Теперь после instanceof можно сразу же использовать объект нужного типа в коде, что делает программу более читабельной и компактной.

#java #PatternMatching #instanceof
Please open Telegram to view this post
VIEW IN TELEGRAM
👍261