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

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

✍️По всем вопросам: @Pascal4eg
Download Telegram
⌨️ StringJoiner - это класс, который предназначен для объединения строк с использованием разделителя между ними. Этот класс был введен в Java 8 в пакете java.util. Он облегчает создание текстовых последовательностей, объединяя строки и вставляя разделители между ними.

Вызов метода toString() возвращает объединенную строку с разделителями и окружающими символами.

Вы также можете использовать метод setEmptyValue() для определения значения, которое будет использоваться, если StringJoiner остается пустым.


StringJoiner sj = new StringJoiner(", ", "[" , "]");
sj.setEmptyValue("No items");
System.out.println(sj.toString()); // No items

sj.add("Apple").add("Banana").add("Cherry");
System.out.println(sj.toString()); // [Apple, Banana, Cherry]


#java #StringJoiner
Please open Telegram to view this post
VIEW IN TELEGRAM
👍181
⌨️ Метод forEachOrdered интерфейса Stream

Метод forEachOrdered в интерфейсе Stream используется для обработки каждого элемента потока с сохранением порядка обработки, даже если поток является параллельным.

В отличие от метода forEach(), который не гарантирует порядок выполнения в параллельных потоках, метод forEachOrdered() всегда сохраняет порядок элементов, как если бы поток был последовательным.

Этот метод полезен, если вам нужно выполнить действия для каждого элемента в параллельном потоке, но при этом важен порядок обработки (например, вывод или запись данных в определенной последовательности).

Параллельный поток с forEach:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.parallelStream().forEach(n -> System.out.println(n));
// Порядок не определён, например 3 1 4 2 5


Параллельный поток с forEachOrdered:

numbers.parallelStream()
.forEachOrdered(n -> System.out.println(n));
// 1 2 3 4 5


#java #Stream #forEachOrdered
Please open Telegram to view this post
VIEW IN TELEGRAM
👍122
⌨️ Почему Java не поддерживает перегрузку операторов?

Перегрузка операторов делает код менее читаемым и плохо поддерживаемым. Чтобы сохранить простоту кода, Java не поддерживает перегрузку операторов.

#java #operatorOverloading
Please open Telegram to view this post
VIEW IN TELEGRAM
5
😁39🤣112🐳1
public class Quest {
public static void main(String[] args) {
Integer a = 128;
Integer b = 128;
System.out.print(a == b);

System.out.print("-");

Integer x = 1;
Integer y = 1;
System.out.print(x == y);
}
}

#java #quest
👍21
Что выведет код?
Anonymous Quiz
30%
true-true
4%
true-false
53%
false-true
13%
false-false
🎉43
⌨️ 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍163🍾2🔥1
⌨️ Вычислить максимальное значение в одну строку

В этом нам помогут наши любимые стримы.

Так:
List<Integer> iList = List.of(1,2,3,4,5);
Integer max = iList.stream().reduce(Integer::max).orElse(null);
System.out.println(max);


А еще лучше вот так:
List<Integer> iList = List.of(1,2,3,4,5);
iList.stream().reduce(Integer::max).ifPresent(System.out::println);


#java #Stream #max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍91
⌨️ Несколько способов избежать NullPointerException:

✔️ Используйте класс Optional из пакета java.util для работы с потенциально пустыми значениями.

✔️ При сравнении константы с переменной, полученной извне, вызывайте метод equals() на константе, а не на переменной.

✔️ Для сравнения двух переменных используйте метод java.util.Objects#equals.

✔️ Применяйте библиотеки, обеспечивающие null-безопасность, например, Apache Commons StringUtils.

✔️ Всегда вызывайте методы equals() и equalsIgnoreCase() на объектах, которые гарантированно не равны null.

✔️ Вместо метода toString(), который может вызвать NullPointerException, используйте String.valueOf().

✔️ Используйте аннотации @NotNull и @Nullable, доступные в вашей IDE, для указания допустимости null.

✔️ Возвращайте пустую коллекцию (например, java.util.Collections#emptyList) вместо null при работе с коллекциями в методах.

#java #NullPointerException #Optional
Please open Telegram to view this post
VIEW IN TELEGRAM
👍164🔥1👏1
⌨️ Семейство классов *SummaryStatistics

Классы DoubleSummaryStatistics, IntSummaryStatistics и LongSummaryStatistics служат для хранения агрегированных данных о числовом потоке. А конкретно: количество, сумма, минимальное, максимальное и среднее.

Пример:

List<Integer> iList = List.of(1, 2, 3);
IntSummaryStatistics stats = iList.stream().collect(Collectors.summarizingInt(i -> i));
System.out.println(stats);
// IntSummaryStatistics{count=3, sum=6, min=1, average=2,000000, max=3}


#java #IntSummaryStatistics #DoubleSummaryStatistics #LongSummaryStatistics
Please open Telegram to view this post
VIEW IN TELEGRAM
👍91
⌨️ Логические операторы

«И» (AND): конъюнкция, логическое умножение

true && true = true
false && false = false
true && false = false
false && true = false

true & true = true
false & false = false
true & false = false
false & true = false

Побитовые операции:
1010
&&&&
1001
====
1000


Включающее «ИЛИ» (OR): дизъюнкция, логическое сложение

true || true = true
false || false = false
true || false = true
false || true = true

true | true = true
false | false = false
true | false = true
false | true = true

Побитовые операции:
1010
||||
1001
====
1011


Исключающее «ИЛИ» (XOR): строгая дизъюнкция, логическое вычитание

true ^ true = false
false ^ false = false
true ^ false = true
false ^ true = true

Побитовые операции:
1010
^^^^
1001
====
0011


«НЕ» (NOT): инверсия, отрицание

!true = false
!false = true

Побитовый унарный оператор NOT:
~~
01
==
10



Порядок выполнения операторов

Когда в выражении несколько логических операторов, результат вычисляется с учётом их приоритета. Если нет логических скобок, то операции выполняются в таком порядке:

! ~ (NOT)
& (AND)
^ (XOR)
| (OR)
&& (условный AND)
|| (условный OR)

Если одинаковые операции стоят по соседству, то раньше выполняется та, что левее.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112
public class Survive {
private Survive internalInstance = new Survive();

public Survive() throws Exception {
throw new Exception("I'm not coming out");
}

public static void main(String[] args) {
try {
Survive b = new Survive();
System.out.println("WIN!");
} catch (Exception ex) {
System.out.println("LOSE!");
}
}
}


#java #quest
⌨️ 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
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍3
⌨️ ORM и JPA

ORM (Object-Relational Mapping) — это технология, которая позволяет автоматически преобразовывать данные между объектами в программном коде и записями в реляционной базе данных. Благодаря ORM, программисты могут работать с базой данных на уровне объектов, а не SQL-запросов, что упрощает разработку.

JPA (Java Persistence API) — это стандарт спецификации ORM в Java. JPA определяет набор интерфейсов и аннотаций для работы с объектами и их сохранением в базу данных. Однако JPA сама по себе не является реализацией, а только задает стандарт. Реализации JPA включают Hibernate, EclipseLink и другие.

#java #jpa
Please open Telegram to view this post
VIEW IN TELEGRAM
👍151
⌨️ HQL (Hibernate Query Language) — это язык запросов, используемый в Hibernate для работы с объектами, а не с таблицами базы данных. HQL основан на синтаксисе SQL, но оперирует сущностями и их атрибутами, вместо строк и столбцов базы данных.

Особенности HQL:

✔️ Запросы формулируются относительно классов и их полей, а не таблиц.

✔️ Поддерживает агрегатные функции (например, COUNT, SUM).

✔️ Поддерживает JOIN для работы с ассоциациями между объектами.

✔️ HQL автоматически преобразуется в SQL, что облегчает работу с реляционной базой данных, абстрагируя детали.

Пример HQL-запроса:

SELECT u FROM User u WHERE u.name = :name


Здесь User — это класс сущности, а запрос вернет объекты этого класса.

#java #HQL #Hibernate
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
public class Quest {
public static void main(String[] args) {
int[][] tests = {
{6, 5, 4, 3, 2, 1},
{1, 2},
{1, 2, 3},
{1, 2, 3, 4},
{1}
};
int n = 0;
try {
int i = 0;
while (true) {
if (thirdElementIsThree(tests[i++])) n++;
}
} catch (ArrayIndexOutOfBoundsException e) {
}
System.out.println(n);
}

private static boolean thirdElementIsThree(int[] a) {
return (a.length >= 3) & (a[2] == 3);
}
}


#java #quest
5
🌱 Spring Boot - это инструмент, который значительно упрощает разработку приложений на основе Spring, предоставляя возможность создавать автономные, готовые к использованию приложения с минимальной конфигурацией.

Автоконфигурация
Spring Boot автоматически настраивает компоненты приложения на основе зависимостей, которые вы добавляете в проект. Это избавляет от необходимости писать обширные XML-конфигурации или классы конфигурации.

Встроенные серверы
Spring Boot предоставляет возможность запускать приложение с встроенными серверами, такими как Tomcat или Jetty. Это означает, что вам не нужно отдельно настраивать сервер — приложение можно запустить как обычный JAR-файл.

Spring Initializr
Веб-инструмент, который позволяет быстро генерировать новый проект Spring Boot с нужными зависимостями, что делает старт разработки ещё проще.

Actuator
Модуль для мониторинга и управления приложением на продакшене. Он предоставляет различные эндпоинты для проверки состояния, статистики и метрик приложения.

Миграции баз данных
Spring Boot поддерживает интеграцию с инструментами миграции баз данных, такими как Flyway и Liquibase, что упрощает управление схемами базы данных.

#java #SpringBoot
Please open Telegram to view this post
VIEW IN TELEGRAM
👍121🔥1
🌱 Service Discovery это механизм, который позволяет распределенным приложениям (микросервисам) динамически находить друг друга для взаимодействия, независимо от того, где они развернуты (например, в облаке или локально). Это особенно важно для микросервисной архитектуры, где сервисы могут масштабироваться горизонтально, изменять свои IP-адреса и запускаться на различных узлах сети.

Spring Framework предлагает решения для реализации Service Discovery, такие как Spring Cloud, который интегрируется с популярными механизмами регистрации сервисов, такими как: Netflix Eureka, HashiCorp Consul, Apache Zookeeper.

Как работает процесс Service Discovery:

✔️ Регистрация сервиса — каждый микросервис при запуске автоматически регистрируется в реестре (например, Eureka или Consul), передавая своё местоположение (IP и порт).

✔️ Обнаружение сервиса — при необходимости взаимодействовать с другим микросервисом, сервис может запрашивать реестр для получения списка доступных сервисов и их адресов.

✔️ Health Checks — в большинстве систем Service Discovery интегрированы проверки состояния сервисов. Если сервис становится недоступен, он удаляется из реестра.


Зачем это нужно?

✔️ Масштабируемость: При динамическом добавлении и удалении экземпляров сервисов, они автоматически обнаруживаются и учитываются другими сервисами.

✔️ Гибкость развертывания: Сервисы могут развертываться на разных машинах и сетях, не требуя жесткой привязки к IP-адресам.

✔️ Устойчивость: В случае отказа одного из экземпляров сервиса другие сервисы могут быть обнаружены и использованы.

#java #ServiceDiscovery
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51