Pascal4eg / Java

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

Унарный оператор

boolean b = false;
System.out.println(b); // false
System.out.println(!b); // true

int i = -5;
System.out.println(i); // -5
System.out.println(-i); // 5
System.out.println(+i); // -5

int j = 5;
int k = 5;
System.out.println(++j + k++); // 11
System.out.println(j); // 6
System.out.println(k); // 6

Унарный оператор - это оператор, который принимает на вход один аргумент и возвращает некоторое значение.

К унарным операторам относятся: +, -, !
А так же, пре-унарный оператор и пост-унарный оператор.

Читать дальше

Varargs (Variable Arguments List)

public static void main(String[] args) {
    System.out.println(concat("one", 1, BigDecimal.ONE));
    // one,1,1
}

private static String concat(Object... args) {
    return Arrays.stream (args)
            .map (Object::toString)
            .collect(Collectors.joining(","));
}

Varargs (Variable Arguments List, изменяющийся список аргументов) — это способ создания методов, которые могут принимать произвольное количество аргументов одного типа (от нуля и более). Данная возможность появилась в JDK 5.

Запись вида Object... args и есть varargs.

Читать дальше

Бесконечные потоки

Stream<Integer> infiniteStream = Stream.iterate(0, i -> i + 2);
List<Integer> intList = infiniteStream
                        .limit(10)
                        .collect(Collectors.toList());
// 0, 2, 4, 6, 8, 10, 12, 14, 16, 18

Supplier<UUID> randomUUIDSupplier = UUID::randomUUID;
Stream<UUID> infiniteUUIDStream = Stream.generate(randomUUIDSupplier);
List<UUID> uuidList = infiniteUUIDStream
                        .skip(10) // пропустить первые 10
                        .limit(10)
                        .collect(Collectors.toList());

Интерфейс Stream имеет два статических метода для генерации бесконечных потоков: iterate() и generate().

Читать дальше

Stream

Все операции Stream делятся на промежуточные и терминальные и объединяются в потоковые конвейеры.

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

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

Они составляют конвейер выполнения Stream. Промежуточную операцию можно добавить в конвейер Stream методами:
filter()
map()
flatMap()
distinct()
sorted()
peek()
limit()
skip()

Читать дальше

Защита от повторного запроса с помощью БД

Если вы разрабатываете Веб-приложение или REST-сервис, то рано или поздно столкнётесь с повторными запросами. Что имеется в виду? Объясню на примере Веб-страницы с кнопкой. По нажатию на кнопку, на бэкенд отправляется запрос. Запрос, соответственно, синхронный и пока серверная часть делает какую-то работу, браузер клиента показывает, что загружает страницу. Если это происходит продолжительное время, клиент может подумать, что его запрос завис и нажать кнопку ещё раз. Также повторное нажатие может произойти случайно.

Какая тут может произойти проблема? Если это, например, какой-то запрос данных, то в общем-то проблемы и нет, но если это действие, которое должно отработать только один раз, то тут могут быть весьма неприятные последствия. Для примера в интернет-магазине собрана корзина и создан заказ на оплату (статус REGISTERED), далее по нажатию кнопки "оплатить" с клиента списывают деньги и переводят заказ в статус оплачен (PAID). И если в этом процессе произойдёт двойной запрос, то с клиента могут списать деньги за заказ два раза.

Читать статью

Читать дальше

Комбинирование предикатов

List<String> fruits = List.of("apple", "orange", "pineapple", "grapefruit", "melon");
Predicate<String> isEqualsOrange = Predicate.isEqual("orange");
Predicate<String> isEqualsGrapefruit = Predicate.isEqual("grapefruit");
Predicate<String> isEqualsCitrus = isEqualsOrange.or(isEqualsGrapefruit);
Predicate<String> isNotEqualsCitrus = isEqualsCitrus.negate();

fruits.stream().filter(isEqualsOrange).forEach(System.out::println);
// orange

fruits.stream().filter(isEqualsCitrus).forEach(System.out::println);
// orange grapefruit

fruits.stream().filter(isNotEqualsCitrus).forEach(System.out::println);
// apple pineapple melon

🧩 Predicate - встроенный функциональный интерфейс, добавленный в Java 8 в пакет java.util.function.

Читать дальше

Запись (record)

public record Point (int x, int y) { }

public static void main(String[] args) {
    Point point = new Point(100, 100);
    System.out.println(point);
}
// Point[x=100, y=100]

📝 Запись (record) — это класс, объявленный с ключевым словом record вместо ключевого слова class. Запись служит контейнером неизменяемых данных и предназначена для лаконичного описания DTO (Data Transfer Object).

Читать дальше

Sentry for Java

Sentry for Java — это программный инструмент, призванный помочь разработчикам отслеживать и управлять ошибками, исключениями и сбоями в приложениях Java.

Читать дальше

Double braces инициализация

// Double braces initialization
List<String> planets = new ArrayList<>() {{
    add("Mercury");
    add("Venus"); 
    add("Earth"); 
    add("Mars");
    add("Jupiter");
    add("Saturn"); 
    add("Uranus"); 
    add("Neptune");
}};

Double braces инициализация - это создание и инициализация объекта в одном java выражении. Чаще всего используется с коллекциями.

На самом деле в этот момент происходит создание анонимного внутреннего класса, расширяющего ArrayList и определение в нём блока инициализации экземпляра.

Читать дальше

Stream API

Stream API появился в Java 8 и существенно упростил работу с коллекциями. Теперь можно писать короче и красивее фильтрацию, сортировку и обработку данных.

private final List<Property> properties = getProperties();

/**
 * Поиск свойства по имени в списке
 * @param propName наименование свойства
 * @return найденное свойство или null если не найдено
 */
public Property getPropertyByName(String propName) {
    return properties.stream().filter(p -> p.getName().equals(propName)).findFirst().orElse(null);
}
Читать дальше