Библиотека Java разработчика
10.8K subscribers
1.14K photos
564 videos
58 files
1.44K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
Что такое «лямбда»? Какова структура и особенности использования лямбда-выражения?

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

Основу лямбда-выражения составляет лямбда-оператор, который представляет стрелку ->. Этот оператор разделяет лямбда-выражение на две части: левая часть содержит список параметров выражения, а правая собственно представляет тело лямбда-выражения, где выполняются все действия.

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

interface Operationable {
int calculate(int x, int y);
}

public static void main(String[] args) {
Operationable operation = (x, y) -> x + y;
int result = operation.calculate(10, 20);
System.out.println(result); //30
}

По факту лямбда-выражения являются в некотором роде сокращенной формой внутренних анонимных классов, которые ранее применялись в Java.

Отложенное выполнение (deferred execution) лямбда-выражения- определяется один раз в одном месте программы, вызываются при необходимости, любое количество раз и в произвольном месте программы.

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

operation = (int x, int y) -> x + y;
//При написании самого лямбда-выражения тип параметров разрешается не указывать:
(x, y) -> x + y;
//Если метод не принимает никаких параметров, то пишутся пустые скобки, например:
() -> 30 + 20;
//Если метод принимает только один параметр, то скобки можно опустить:
n -> n * n;


Конечные лямбда-выражения не обязаны возвращать какое-либо значение.

interface Printable {
void print(String s);
}

public static void main(String[] args) {
Printable printer = s -> System.out.println(s);
printer.print("Hello, world");
}

Блочные лямбда-выражения обрамляются фигурными скобками. В блочных лямбда-выражениях можно использовать внутренние вложенные блоки, циклы, конструкции if, switch, создавать переменные и т.д. Если блочное лямбда-выражение должно возвращать значение, то явным образом применяется оператор return:

Operationable operation = (int x, int y) -> {
if (y == 0) {
return 0;
}
else {
return x / y;
}
};


Передача лямбда-выражения в качестве параметра метода:

interface Condition {
boolean isAppropriate(int n);
}

private static int sum(int[] numbers, Condition condition) {
int result = 0;
for (int i : numbers) {
if (condition.isAppropriate(i)) {
result += i;
}
}
return result;
}

public static void main(String[] args) {
System.out.println(sum(new int[] {0, 1, 0, 3, 0, 5, 0, 7, 0, 9}, (n) -> n != 0));
}


👉@BookJava
👍9👏1
К каким переменным есть доступ у лямбда-выражений?

Доступ к переменным внешней области действия из лямбда-выражения очень схож к доступу из анонимных объектов. Можно ссылаться на:

⚫️неизменяемые (effectively final - не обязательно помеченные как final) локальные переменные;
⚫️поля класса;
⚫️статические переменные.
К методам по умолчанию реализуемого функционального интерфейса обращаться внутри лямбда-выражения запрещено.


Как отсортировать список строк с помощью лямбда-выражения?

public static List<String> sort(List<String> list){
Collections.sort(list, (a, b) -> a.compareTo(b));
return list;
}


👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Что такое «ссылка на метод»?

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

⚫️имя_класса::имя_статического_метода для статического метода;
⚫️объект_класса::имя_метода для метода экземпляра;
⚫️название_класса::new для конструктора.
Результат будет в точности таким же, как в случае определения лямбда-выражения, которое вызывает этот метод.

private interface Measurable {
public int length(String string);
}

public static void main(String[] args) {
Measurable a = String::length;
System.out.println(a.length("abc"));
}

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


👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
Как применяют технологию SPI

Service Provider Interface – технология из стандартной поставки JavaSE. Этой технологией реализуется IoC, не являющаяся при этом DI. С помощью SPI можно легко и без дополнительных инструментов поставлять конкретные реализации сервисов отдельными jar-файлами. Применение обычно похоже на механизм плагинов.

Два основных понятия SPI – это service и service provider. Service – интерфейс или абстрактный класс, который объявляет API требуемого сервиса, и предоставляется основным приложением. Service provider – реализация этого API, наследник класса/интерфейса сервиса, который динамически поставляется в основное приложение библиотекой-плагином. Для одного сервиса может быть предоставлено несколько провайдеров из одной или нескольких библиотек.

На интерфейс сервиса не накладывается никаких ограничений. Провайдер же обязан реализовывать этот интерфейс, и иметь конструктор без параметров. Внутри jar-файла в директории META-INF/services лежат текстовые файлы, где имя файла – полное имя сервиса, а его строчки – полные имена провайдеров этого сервиса, которые поставляются этой библиотекой.

Для получения провайдеров всех библиотек приложения используется класс ServiceLoader. Это итератор по сервис-провайдерам, а создается он статическим методом load, в который параметром передается интерфейс/абстрактный класс интересующего сервиса.

Доступ к файлам-ресурсам из classpath обеспечивается загрузчиком классов, поэтому дополнительно при загрузке можно указать специфический загрузчик. С появлением модульности в Java 9 можно также указать модуль.

SPI повсеместно используется в стандартной библиотеке JDK. С его помощью подключаются JDBC-драйверы. Через ServiceLoader также загружаются таймзоны, системные настройки, кодировки, провайдеры файловой системы и многое другое.

👉@BookJava
👍7
Какие виды ссылок на методы вы знаете?

⚫️на статический метод;
⚫️на метод экземпляра;
⚫️на конструктор.

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Что такое «функциональные интерфейсы»?

Функциональный интерфейс - это интерфейс, который определяет только один абстрактный метод.

Чтобы точно определить интерфейс как функциональный, добавлена аннотация @FunctionalInterface, работающая по принципу @Override. Она обозначит замысел и не даст определить второй абстрактный метод в интерфейсе.

Интерфейс может включать сколько угодно default методов и при этом оставаться функциональным, потому что default методы - не абстрактные.

👉@BookJava
👍5
Для чего нужны функциональные интерфейсы Function<T,R>, DoubleFunction<R>, IntFunction<R> и LongFunction<R>?

Function<T, R> - интерфейс, с помощью которого реализуется функция, получающая на вход экземпляр класса T и возвращающая на выходе экземпляр класса R.

Методы по умолчанию могут использоваться для построения цепочек вызовов (compose, andThen).

Function<String, Integer> toInteger = Integer::valueOf;
Function<String, String> backToString = toInteger.andThen(String::valueOf);
backToString.apply("123"); // "123"



⚫️DoubleFunction<R> - функция получающая на вход Double и возвращающая на выходе экземпляр класса R;
⚫️IntFunction<R> - функция получающая на вход Integer и возвращающая на выходе экземпляр класса R;
⚫️LongFunction<R> - функция получающая на вход Long и возвращающая на выходе экземпляр класса R.

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Что делает семафор?

Семафор – один из старейших примитивов синхронизации. Он был изобретен Дейкстрой в 1968 году. По большому счету это счетчик, который можно увеличивать и уменьшать из разных потоков. Уменьшение до 0 блокирует уменьшающий поток. Состояние, когда счетчик больше нуля называют сигнальное состояние, операцию его увеличения – release (освобождение) или signal, уменьшения – acquire (захват) или wait.

На практике можно представить, что release – выделение квоты доступа к критической секции программы. acquire – использование необходимого объема доступной квоты, или ожидание, если её не хватает.

В Java семафор реализован классом Semaphore. Состоит этот класс в основном из разных форм методов acquire (с таймаутом, с игнорированием InterruptedException, неблокирующий) и release. Методы могут принимать параметр permits – тот самый объем квот, которые необходимо освободить/захватить.

Несколько вспомогательных методов позволяют узнать больше о количестве и составе очереди потоков, которые ждут освобождения пермитов. А методы availablePermits и drainPermits позволяют узнать количество оставшихся пермитов, и захватить их все соответственно. В конструкторе конфигурируются изначальное количество пермитов, и свойство fair (аналогичное свойству ReentrantLock).

👉@BookJava
👍5
Media is too big
VIEW IN TELEGRAM
Обновление Java с 17 на 21: через тернии к звездам

Меня зовут Денис, я тимлид команды R&D в Naumen Service Management Platform.

Как большие почитатели языка Java, мы, Naumen Service Management Platform, стараемся мигрировать на свежие версии языка. Причин множество: это и улучшенная безопасность, и появление крутых языковых фич, и буст перформанса. Но путь не всегда оказывается простым.

В докладе я расскажу, с какими проблемами и препятствиями мы столкнулись при обновлении продукта Naumen SMP на новую LTS версию Java. Также поделюсь мыслями, а зачем вообще стоит обновляться.

Доклад будет полезен разработчикам и техлидам, которые задумываются или уже планируют миграцию их систем на Java 21.

https://habr.com/ru/companies/naumen/articles/822639/

👉@BookJava
👍3👎1🤔1
Для чего нужны функциональные интерфейсы UnaryOperator<T>, DoubleUnaryOperator, IntUnaryOperator и LongUnaryOperator?

UnaryOperator<T> (унарный оператор) принимает в качестве параметра объект типа T, выполняет над ними операции и возвращает результат операций в виде объекта типа T:

UnaryOperator<Integer> operator = x -> x * x;
System.out.println(operator.apply(5)); // 25


⚫️DoubleUnaryOperator - унарный оператор получающий на вход Double;
⚫️IntUnaryOperator - унарный оператор получающий на вход Integer;
⚫️LongUnaryOperator - унарный оператор получающий на вход Long.

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Как Spring Framework реализует паттерн Dependency Injection?

Инверсия контроля (inversion of control, IoC) – принцип проектирования, по которому контроль над потоком управления передается фреймворку. Управляющий и прикладной код разделяются. При разработке модуля этот подход избавляет от необходимости знать о других модулях программы и деталях их взаимодействия. Такой код становится более переипользуемым и модульным, уменьшает связность.

Внедрение зависимостей (Dependency Injection, DI) – одна из реализаций IoC. При взаимодействии с другими модулями, программа оперирует высокоуровневыми абстракциями, тогда как конкретная её реализация поставляется фреймворком.

Стандартная реализация DI – фреймворк инстанциирует все сервисы, и складывает их в IoC-контейнер. При этом специальная сущность, Service Locator, занимается поиском соответствия реализаций абстракциям и их внедрением.

Spring – большой набор различных библиотек. DI реализуется одной из основных библиотек – Spring IoC.

Сущности бизнес-логики в Spring, как и в JavaEE называются beans. Бины объявляются различными способами, корни большинства из них лежат в понятии Configuration. В качестве контейнера бинов выступает ApplicationContext. Чтобы передать инициализацию зависимости контексту, она помечается аннотацией @Autowired.

👉@BookJava
🔥41👍1
Реализация авторизации на основе ролей в Spring Boot с помощью Keycloak

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

В предыдущей статье мы узнали, как защитить Spring Boot REST API с помощью Keycloak, используя протокол аутентификации OpenID Connect.

В этой статье мы добавим авторизацию на основе ролей.

Цель состоит в том, чтобы разрешить доступ к некоторым конечным точкам только пользователям с определенной ролью. Точнее, мы собираемся ограничить доступ к конечной точке DELETE и сделать его доступным только пользователям с ролью администратора.

https://gauthier-cassany.com/posts/spring-boot-keycloak-roles

👉@BookJava
👍5
Spring Boot 3.2: замените свой RestTemplate на RestClient

В мире Spring Boot отправка HTTP запросов к внешним сервисам является весьма распространенной задачей. Традиционно при достижении этой цели разработчики полагались на RestTemplate. Однако, по мере развития Spring Framework, на свет появился новый и более мощный способ обработки HTTP запросов: так называемый WebClient. Spring Boot 3.2 представил нам новый API для REST запросов: RestClient, использующий те же принципы fluent api, что и WebClient.

RestClient предлагает нам более современные и интуитивно понятные способы взаимодействия с RESTful сервисами.

https://habr.com/ru/companies/spring_aio/articles/822529/

👉@BookJava
👍31
Что такое StringJoiner?

⚫️ObjDoubleConsumer<T> - операция, которая принимает два аргумента классов T и Double, производит с ними некоторое действие и ничего не возвращает;
⚫️ObjLongConsumer<T> - операция, которая принимает два аргумента классов T и Long, производит с ними некоторое действие и ничего не возвращает;
⚫️ObjIntConsumer<T> - операция, которая принимает два аргумента классов T и Integer, производит с ними некоторое действие и ничего не возвращает.

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Совет по Spring Boot💡

Когда вам нужно настроить bean, предоставляемый Spring Boot, проверьте наличие интерфейсов *Customizer - велика вероятность, что вы сможете настроить bean, не отказываясь от автоконфигурации.

👉@BookJava
👍12
Совет по Spring Boot💡

После аннотации bean с @Validated, вы можете использовать параметры метода валидации с аннотациями валидации bean, такими как @NotNull, @NotBlank и т.д.

👉@BookJava
👍54
Чем отличается ReentrantLock от обычного Lock?

Lock – это интерфейс, ReentrantLock – его реализация. «Reentrant» говорит о том, что один и тот же поток может перезахватывать уже захваченный лок. Интерфейс не требует этого свойства. Обычный блок synchronized тоже является reentrant – вложенная синхронизация на том же мониторе отработает без проблем.

Примеры не-reentrant локов из стандартной библиотеки – представления класса StampedLock, возвращаемые его методами asReadLock() и asWriteLock().

👉@BookJava
👍6
Для чего в стримах предназначены методы flatMap(), flatMapToInt(), flatMapToDouble(), flatMapToLong()?

Метод flatMap() похож на map, но может преобразовывать из нескольких элементов (стримов, массивов, коллекций) один. Например можно преобразовать двумерный массив в одномерный:

int[][] arr = {{1,2}, {5,6}, {3,4}};
Arrays.stream(arr).flatMapToInt(x -> Arrays.stream(x)).forEach(System.out::println);


Или из стрима листов получить один стрим:

public static void main(String[] args) {
List<Human> humans = asList(
new Human("Sam", asList("Buddy", "Lucy")),
new Human("Bob", asList("Frankie", "Rosie")),
new Human("Marta", asList("Simba", "Tilly")));

List<String> petNames = humans.stream()
.map(human -> human.getPets()) //преобразовываем Stream<Human> в Stream<List<Pet>>
.flatMap(pets -> pets.stream())//"разворачиваем" Stream<List<Pet>> в Stream<Pet>
.collect(Collectors.toList());

System.out.println(petNames); // output [Buddy, Lucy, Frankie, Rosie, Simba, Tilly]
}


Или разбить строку по буквам:

Stream
.of("H e l l o", "w o r l d !")
.flatMap((p) -> Arrays.stream(p.split(" ")))
.toArray(String[]::new);//["H", "e", "l", "l", "o", "w", "o", "r", "l", "d", "!"]



flatMapToInt(), flatMapToDouble(), flatMapToLong() - это аналоги flatMap(), возвращающие соответствующий числовой стрим.


👉@BookJava
👍7
Что выбрать, Stack или Queue?

Queue – один из основных интерфейсов Java Collections Framework. В общем случае (но не обязательно) представляет FIFO-коллекцию – элементы можно добавлять в хвост, брать или удалять из головы. Его наследник, интерфейс Deque (double ended queue, двусторонняя очередь), позволяет манипулировать элементами на обеих сторонах.

StackLIFO коллекция. То есть добавлять и удалять элементы можно только с одного конца. Кроме того, стек наследуется от Vector, и тоже является пересинхронизированным и устаревшим. Его документация явно рекомендует предпочесть использовать Deque.

👉@BookJava
👍5
Подборка Telegram каналов для программистов

Системное администрирование 📌
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux


https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)

https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика

https://t.me/itmozg Программисты, дизайнеры, новости из мира IT.
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике

https://t.me/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста

1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С

Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах

Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus

Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах

GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных

Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin

Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано

Разработка игр 📌
https://t.me/game_devv Все о разработке игр

Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT

Чат программистов📌
https://t.me/developers_ru

Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
https://t.me/books_reserv Книги для программистов

БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning

Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию

QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика

Шутки программистов 📌
https://t.me/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_1 Статьи из "Хакера"

Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров

Английский 📌
https://t.me/UchuEnglish Английский с нуля

Математика 📌
https://t.me/Pomatematike Канал по математике

Excel лайфхак📌
https://t.me/Excel_lifehack