Java Portal | Программирование
11.6K subscribers
858 photos
67 videos
28 files
682 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
加入频道
Strategy Pattern без занудства

Ситуация: вы пишете платёжную систему

У вас есть PaymentService, поддерживающий оплату кредитной картой.

Вы пишете:

public void pay(String method) {
if (method.equals("creditcard")) {
// логика оплаты кредиткой
}
}


Потом добавляют PayPal, UPI, крипту, Apple Pay, кошельки, NetBanking и тд.. 😢

Теперь ваш метод выглядит вот так:

if (method.equals("creditcard")) {
// логика кредитки
} else if (method.equals("paypal")) {
// логика PayPal
} else if ...


Вы тонете в аду if-else. Каждый раз при добавлении нового способа оплаты:

> Вы трогаете старый код
> Рискуете сломать существующую логику
> Нельзя нормально протестировать стратегии
> Нарушается принцип OCP (Open/Closed)

В чём настоящая проблема?

1. Ваш код слишком жёстко связан с конкретными реализациями оплат
2. Добавление новых стратегий требует изменения существующего кода
3. Тестировать/переиспользовать отдельные стратегии — сложно
4. PaymentService теперь отвечает за слишком многое

Как Strategy Pattern вас спасает

1. Создаёшь интерфейс PaymentStrategy
2. Для каждой оплаты — свой класс: CreditCardPayment, PayPalPayment, UPIPayment
3. PaymentService просто вызывает .pay() на нужной стратегии

Добавить новый способ? Просто пишешь новый класс
Никаких if-else
Стратегии изолированы и легко тестируются

interface PaymentStrategy {
void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Плачу " + amount + " с помощью кредитки");
}
}

class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Плачу " + amount + " через PayPal");
}
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Имбовая библиотека цветов для Kotlin Multiplatform

Если ты пилишь на Kotlin и хочешь красивые цвета под любую платформу — зацени compose-pipette

Поддерживает:

> JVM
> Android (от API 21)
> Kotlin/JS
> Kotlin/WASM
> macOS (пока не тестили)
> iOS (тоже не тестили)

Поддержи пост лайком ❤️

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
В Java лямбда-выражение создаёт экземпляр функционального интерфейса. Во время выполнения этот экземпляр создаётся с помощью класса LambdaMetaFactory

Следующий код на Java создаёт объект Function<String, String>

Function<String, String> f = s -> s.toUpperCase();


Во время выполнения объект создаётся с помощью кода, аналогичного следующему:

@SuppressWarnings("unchecked")
void main() throws Throwable {
MethodHandles.Lookup lookup;
lookup = MethodHandles.lookup();

CallSite callSite;
callSite = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(Function.class),
MethodType.methodType(Object.class, Object.class),
lookup.findStatic(
getClass(),
"lambda",
MethodType.methodType(String.class, String.class)
),
MethodType.methodType(String.class, String.class)
);

MethodHandle target;
target = callSite.getTarget();

Function<String, String> f;
f = (Function<String, String>) target.invokeExact();

String msg;
msg = f.apply("Hello, World!");

IO.println(msg);
}

private static String lambda(String s) {
return s.toUpperCase();
}


При выполнении этот код выведет в консоль HELLO, WORLD! ❤️

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Курс по конкурентному программированию от Ильи Сергеева

Если хочешь разобраться в параллельности, потоках, акторной модели и распределёнке — лови топовый курс от препода Yale-NUS

— Scala для конкурентного кода
— Мьютексы, блокировки, атомики
— Futures и async
— Акторы и обмен сообщениями
— Распределённый консенсус (в т.ч. BFT)

Можешь поблагодарить лукасом 😍

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Начиная с JDK 12, появилась новая фича — java.text.CompactNumberFormat. Она позволяет компактно отображать большие числа

Пример:

Locale.setDefault(Locale.US);
NumberFormat compact = NumberFormat.getCompactNumberInstance();

System.out.println(compact.format(1));
System.out.println(compact.format(999));
System.out.println(compact.format(2_000));
System.out.println(compact.format(55_555));
System.out.println(compact.format(3_777_999));
System.out.println(compact.format(Integer.MAX_VALUE));


Вывод:

1
999
2K
56K
4M
2B


Также доступен стиль LONG:

NumberFormat compact;
compact = NumberFormat.getCompactNumberInstance(Locale.US, Style.LONG);


Результат:

1
999
2 thousand
56 thousand
4 million
2 billion


Идеально для UI, отчетов и всего, где важна краткость 💖

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Разработчики, вот вам шпаргалка по техникам синхронизации потоков в Java 🧑‍💻

synchronized блок/метод -> использует встроенную блокировку объекта для обеспечения взаимного исключения.

ReentrantLock -> явная блокировка с более гибкими возможностями по сравнению с synchronized.

volatile- > гарантирует видимость изменений переменной между потоками.

Атомарные переменные (AtomicInteger и др.) -> обеспечивают атомарные операции без блокировок.

Semaphore -> управляет доступом к ресурсу с ограниченным числом разрешений.

CountDownLatch -> позволяет одному или нескольким потокам ожидать завершения операций в других потоках.

CyclicBarrier -> позволяет группе потоков дождаться друг друга до продолжения выполнения.

ReadWriteLock -> разрешает множественные параллельные чтения, но только одну запись.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Вот хороший пример очень плохого использования метки в Java:

void main() {
do onlyOnce: {
IO.println("Один раз?");
break onlyOnce;
} while (true);
}


Компилируется без ошибок. При выполнении выводит:

Один раз?
Один раз?
Один раз?
Один раз?
Один раз?
...


Это приводит к бесконечному циклу 🙂

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Используйте DTO для запросов и ответов

Никогда не передавайте сущности напрямую — всегда преобразовывайте их в DTO и обратно

🤍 база

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Отличное руководство по безопасности Java-приложений

🔜 Читать: клик

👉 Java Portal | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
JDK 22 представил класс java.text.ListFormat. Используйте его, когда нужно отформатировать список строк в удобочитаемый вид. Например, вот такая программа:

final List<String> days = List.of("Mon", "Wed", "Fri");

void main() {
print(Type.STANDARD);
print(Type.OR);
print(Type.UNIT);
}

private void print(Type type) {
print(type, Style.FULL);
print(type, Style.SHORT);
print(type, Style.NARROW);
}

private void print(Type type, Style style) {
var format = ListFormat.getInstance(Locale.US, type, style);
var result = format.format(days);
System.out.printf("%-8s + %-7s: %s%n", type, style, result);
}


Вывод:

STANDARD + FULL   : Mon, Wed, and Fri
STANDARD + SHORT : Mon, Wed, & Fri
STANDARD + NARROW : Mon, Wed, Fri
OR + FULL : Mon, Wed, or Fri
OR + SHORT : Mon, Wed, or Fri
OR + NARROW : Mon, Wed, or Fri
UNIT + FULL : Mon, Wed, Fri
UNIT + SHORT : Mon, Wed, Fri
UNIT + NARROW : Mon Wed Fri


Также можно использовать ListFormat для разбора отформатированной строки обратно в список

Ставь лайк если полезно 🪑

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Способы сравнения строк в Java

1. == → Сравнивает адреса в памяти
2. .equals() → Сравнивает содержимое строк
3. .compareTo() → Лексикографическое сравнение
4. .equalsIgnoreCase() Сравнивает без учёта регистра

> Подробнее тут 😊

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
В Java можно ставить метку на выражение, которое уже промечено другой меткой. И так хоть до бесконечности.

Полезно? Вряд ли.
Стоит ли использовать? Точно нет.

Но как факт — это работает

Пример:

String question;
to: be: or: not: that: is: the: question = "What?";

out.println(question);


> Код компилируется
> Метки (to:, be:, or: и т.д.) игнорируются, если не используются в break или continue

Вывод:

What?


Иногда Java действительно говорит с нами стихами 🫢

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
В чём разница между throw и throws в Java?

throw

> Используется для явного выбрасывания исключения.
> Синтаксис: throw new ExceptionType("сообщение");
> Применяется внутри метода или блока.

throws

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

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Этот Dockerfile для Spring Boot создаёт образ, который потребляет на 33% меньше памяти по сравнению с образом, собранным с помощью Buildpacks (рекомендуемый Spring способ сборки Docker-образов) 💪

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Упростите свой бизнес-код на Java с помощью Flow DSL

🔜 Читать: клик

👉 Java Portal | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
Хочешь чистые REST API на Java?

Используй:

> @RestController

> @RequestBody

> @PathVariable

> @ResponseStatus

Spring REST помогает писать код просто и понятно 🧑‍💻

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое LinkedList (двусвязный список) в Java?

> Состоит из узлов, где каждый узел содержит данные и ссылки на следующий и предыдущий узлы
> Быстрые вставки и удаления — O(1), если есть ссылка на нужный узел
> Медленный доступ по индексу — O(n), т.к. нужно проходить список последовательно

🔧 Когда использовать:

> Частые вставки и удаления — особенно в начале или в середине списка
> Реализация очередей и деков — удобно добавлять в конец и забирать из начала
> Работа с большими объёмами данных, где перераспределение памяти (как в ArrayList) может быть дорогим. LinkedList не требует непрерывной памяти
> Undo/Redo-механизмы — например, в текстовых редакторах, где нужно быстро добавлять и удалять действия из истории

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Метод FileSystems.newFileSystem(Path) появился ещё в JDK 13 (2019), но многие до сих пор о нём не знают

Он позволяет обращаться к содержимому файла, например ZIP-архива, как к файловой системе.

Пример Java-программы:

void main() {
Path src = Path.of("/opt/jdk-24/lib/src.zip");

try (FileSystem fs = FileSystems.newFileSystem(src)) {
for (Path root : fs.getRootDirectories()) {
try (Stream<Path> walk = Files.walk(root, 1)) {
walk.sorted().forEach(IO::println);
}
}
}
}


Результат выполнения:

/
/java.base
/java.compiler
/java.datatransfer
/java.desktop
/java.instrument
/java.logging
...
/jdk.unsupported
/jdk.unsupported.desktop
/jdk.xml.dom
/jdk.zipfs


До появления этого метода нужно было использовать более сложный код с URI и явно указывать схему:

URI src = URI.create("jar:file:///opt/jdk-24/lib/src.zip");

try (FileSystem fs = FileSystems.newFileSystem(src, Map.of())) {
...
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Как создавать многомодульные проекты в Spring Boot

🔜 Читать: клик

👉 Java Portal | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM