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

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

✍️По всем вопросам: @Pascal4eg
Download Telegram
6.png
53.8 KB
🚀 Stream API появился в Java 8 и существенно упростил работу с коллекциями. Теперь можно писать короче и красивее фильтрацию, сортировку и обработку данных.

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

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

Плюсы: код выглядит проще, красивее и понятнее.

Минусы:
📍 малоизвестный способ инициализации
📍 каждый раз создается дополнительный класс
📍 не работает, если класс, который мы пытаемся расширить, помечен как final
📍 содержит скрытую ссылку на внешний экземпляр, что может привести к утечкам памяти

Именно из за этих минусов данная инициализация является антипаттерном.

В современных версиях java есть более красивые и правильные варианты создания и инициализации коллекций.
Начиная с Java 8 это Stream API, а начиная с java 9 конструкция List.of().
👍62
Sentry for Java — это программный инструмент, призванный помочь разработчикам отслеживать и управлять ошибками, исключениями и сбоями в приложениях Java.

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

Ошибки которые не обрабатываются, Sentry соберёт автоматически, а те которые вы обработали, можно отправить вручную:

} catch (Exception e) {
Sentry.addBreadcrumb("readFile");
Sentry.captureException(e);
}


Подключение: добавить зависимость sentry-spring-boot-starter и прописать в конфиге sentry.dsn
🥰4👍2
📝 Запись (record) — это класс, объявленный с ключевым словом record вместо ключевого слова class. Запись служит контейнером неизменяемых данных и предназначена для лаконичного описания DTO (Data Transfer Object).

Класс, который компилятор создает для вас при создании записи, является окончательным (final).

Этот класс расширяет класс java.lang.Record. Таким образом, ваша запись не может расширять какой-либо класс.

Запись, как и класс, может реализовывать любое количество интерфейсов.

Блок, который следует сразу за именем записи, — (int x, int y) объявляет компоненты записи. Для каждого компонента записи компилятор создает private final поле и метод доступа к нему с тем же именем, что и у этого компонента. В записи может быть объявлено любое количество компонентов.

Компилятор сам создаёт конструктор со всеми перечисленными компонентами записи, а так же реализует методы toString(), equals() и hashCode() с реализацией по умолчанию.

record появился в Java 16.
🔥3
Защита от повторного запроса с помощью БД

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

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

Читать статью
👏62👍1
🔄 Бесконечные потоки

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

iterate(final T seed, final UnaryOperator<T> f) возвращает бесконечный последовательный упорядоченный поток, созданный путем итеративного применения функции f к исходному элементу начального значения, создавая поток, состоящий из начального числа, f(начальное число), f(f(начальное число)) и т. д.

generate(Supplier<? extends T> s) возвращает бесконечный последовательный неупорядоченный поток, в котором каждый элемент создается предоставленным поставщиком (Supplier). Это подходит для генерации константных потоков, потоков случайных элементов и т. д.

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

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

При этом три точки после типа указывают, что метод в качестве аргумента может принимать как массив, так и любую последовательность аргументов, записанных через запятую, которая все равно преобразуется в одномерный массив - «под капотом» компилятор на уровне байт-кода неявно заменяет переданную последовательность массивом. Уже в методе аргумент varargs используется как одномерный массив.

Альтернативой varargs является перегрузка методов или передача в метод массива значений.

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

📌 В качестве ограничения любой метод может использовать varargs только в единственном числе и строго последним аргументом.
❤‍🔥7👍3🔥2
Унарный оператор - это оператор, который принимает на вход один аргумент и возвращает некоторое значение.

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

- (оператор смены знака)
Собственно это всё что он делает - меняет знак переданного аргумента. Ещё есть побочный эффект от применения этого оператора, это повышение типа до int, в случае если аргумент имеет тип byte, short или char.

! - оператор логической инверсии. Применяется только к переменным типа boolean и превращает значение из true в false и наоборот.

Операторы инкремента (++) и декремента (--) применяются к целочисленным переменным и обладают двумя вариациям:
пост-инкремент/декремент (i++ и i--)
пре-инкремент/декремент (++i и --i)
Разница между вариациями в том, что ++i увеличивает переменную и возвращает новое значение, а i++ возвращает старое значение, а только затем увеличивает переменную.

Что же делает унарный + ? Да ничего не делает, только имеет такой же побочный эффект как и унарный -.
🔥7
Какой будет результат выполнения кода на картинке выше?
Anonymous Quiz
29%
x=5 y=9
29%
x=4 y=9
24%
x=4 y=10
18%
Ошибка компиляции
🤩7👍2
🚀🧵 Гармония в параллельном мире Java: Thread-Safe

В мире Java, параллельное выполнение потоков - это норма. Однако без должных мер предосторожности, оно может привести к состоянию гонки (race condition) и ошибкам. Вот почему важно понимать и применять концепцию Thread-Safe.

Thread-Safe означает, что ваш код или структуры данных могут безопасно использоваться из множества потоков, не вызывая нежелательных конфликтов. Как добиться Thread-Safety:

Синхронизация: Используйте synchronized или объекты блокировки (Locks), чтобы гарантировать, что только один поток обращается к ресурсу в определенный момент.

Использование неизменяемых (immutable) объектов: Объекты, которые нельзя изменить после их создания, являются потокобезопасными по определению.

Используйте потокобезопасные структуры данных: Java предоставляет такие структуры, как ConcurrentHashMap, которые спроектированы для безопасного параллельного доступа.

Атомарные операции: Используйте java.util.concurrent.atomic для атомарных операций над переменными.

Грамотное планирование потоков: Учтите порядок выполнения и жизненный цикл потоков.

Тестирование: Пишите тесты для обнаружения потенциальных проблем в параллельном выполнении.

Thread-Safe код - это залог безопасности и эффективности в параллельной Java. Помните об этом, разрабатывая многопоточные приложения.
#ThreadSafety
🔥91👍1
Weak Reference: Слабая связь с объектами

В мире Java, WeakReference - это мощный инструмент для управления памятью. Он позволяет создавать ссылки на объекты, которые могут быть автоматически удалены сборщиком мусора, если на них больше нет сильных ссылок (обычная ссылка на объект).

Чем это полезно? Это помогает избежать утечек памяти в приложениях, где объекты могут оставаться неиспользуемыми, но все еще иметь сильные ссылки.

Пример использования WeakReference:
WeakReference<MyObject> weakRef = new WeakReference<>(new MyObject());
Когда не будет сильных ссылок на MyObject, сборщик мусора автоматически удалит его, освобождая память. Это помогает оптимизировать использование ресурсов и снижать риск утечек памяти.

WeakReference - это мощный инструмент для управления памятью в Java, и его следует использовать там, где это необходимо для обеспечения эффективного управления ресурсами.
#WeakReference #УправлениеПамятью
9🥰2
🛠️ Системы сборки в мире Java — это незаменимые инструменты, которые делают процесс разработки проще и эффективнее.

Что бы ваш код стал работающим приложением, его нужно собрать в файл который можно запустить. Это может быть .war или .jar файл.

1️⃣ Apache Ant: Ant — это классическая система сборки Java, основанная на XML. Она обеспечивает гибкость и контроль над процессом сборки, но требует более подробной настройки в сравнении с Maven и Gradle. Считается устаревшей и практически не используется в современных проектах.

2️⃣ Apache Maven: Эта система сборки известна своей конфигурацией на основе управляемых проектов (POM), что упрощает управление зависимостями и сборку проектов. Maven также предоставляет обширную базу плагинов, которые облегчают автоматизацию различных задач. Конфигурация происходит в pom.xml файлах, соответственно в xml формате. На данный момент является наиболее распространенной системой сборки.

3️⃣ Gradle: Gradle предоставляет гибкую и мощную систему сборки с использованием Groovy DSL. Он позволяет разработчикам определять собственные задачи сборки и легко интегрировать их в проект. Gradle также поддерживает инкрементную сборку, что ускоряет разработку. Считается более современной системой по сравнении с Apache Maven и новые проекты часто создаются с использованием этой системы сборки.

Выбор системы сборки зависит от ваших потребностей и предпочтений. Независимо от того, какую вы выберете, они все помогут упростить и ускорить ваш процесс разработки на Java.
👍14🐳3