🎉3👍1
Основные возможности SpEL:
✔️ Обращение к свойствам:
person.name✔️Вызов методов:
person.getName()✔️ Работа с коллекциями: фильтрация и проекция (
list.?[property > 10]).✔️ Логические и арифметические операции:
age > 18 && hasLicense✔️ Доступ к бинам Spring:
@beanName.method()Простой пример:
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class SpELExample {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
// Пример вычисления простого выражения
String expression = "'Hello, Spring SpEL!'.toUpperCase()";
String result = parser.parseExpression(expression).getValue(String.class);
System.out.println(result); // Вывод: HELLO, SPRING SPEL!
}
}
Использование в аннотациях:
@Component
public class MyBean {
@Value("#{T(java.lang.Math).random() * 100}")
private double randomValue;
@Value("#{systemProperties['user.name']}")
private String userName;
public void printValues() {
System.out.println("Random Value: " + randomValue);
System.out.println("User Name: " + userName);
}
}
✔️
T(java.lang.Math).random() — вызов статического метода Math.random().✔️
systemProperties['user.name'] — доступ к системным свойствам.Использование с коллекциями:
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import java.util.Arrays;
import java.util.List;
public class CollectionExample {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Фильтрация списка
List<Integer> filteredNumbers = (List<Integer>) parser.parseExpression(
"#numbers.?[#this > 2]").getValue(new StandardEvaluationContext(), numbers);
System.out.println(filteredNumbers); // Вывод: [3, 4, 5]
}
}
SpEL является удобным инструментом для внедрения динамического поведения и вычислений в приложениях Spring.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍9❤3
public class Quest {
public static void main(String[] args) {
String s = null;
System.out.println(s instanceof String);
}
}👍2
Что выведет код?
Anonymous Quiz
39%
true
26%
false
29%
<NullPointerException>
6%
<Ошибка компиляции>
👍4🎉1
public class Quest {
public static void greet() {
System.out.println("Hello world!");
}
public static void main(String[] args) {
Quest q = null;
q.greet();
}
}👍3
👍3🎉3😁2❤1
Enum.Внутренне
EnumMap использует массив для хранения значений, где индекс массива соответствует порядковому номеру (ordinal()) элемента перечисления. Это делает его быстрее, чем хэш-таблицы (HashMap) и более экономным по памяти.EnumMap хранит ключи в порядке их объявления в перечислении, что отличает его от большинства других Map (кроме LinkedHashMap).Так как ключи строго ограничены перечислением, это снижает вероятность ошибок при разработке.
🔍 Пример:
import java.util.EnumMap;
enum Action {
START, STOP, PAUSE
}
public class EnumMapExample {
public static void main(String[] args) {
EnumMap<Action, Runnable> actionMap = new EnumMap<>(Action.class);
// Определяем поведение для каждого значения Enum
actionMap.put(Action.START, () -> System.out.println("Starting the process..."));
actionMap.put(Action.STOP, () -> System.out.println("Stopping the process..."));
actionMap.put(Action.PAUSE, () -> System.out.println("Pausing the process..."));
// Пример вызова
Action currentAction = Action.START;
actionMap.get(currentAction).run();
}
}
#Java #EnumMap
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19❤5
IdentityHashMapIdentityHashMap — это необычная реализация Map, которая использует сравнение по ссылкам (==) вместо стандартного метода equals().В
IdentityHashMap два ключа считаются равными только если это один и тот же объект (сравнение по ссылкам).📌 Пример:
java
import java.util.IdentityHashMap;
import java.util.Map;
public class IdentityHashMapExample {
public static void main(String[] args) {
Map<String, String> map = new IdentityHashMap<>();
String key1 = new String("key");
String key2 = new String("key");
map.put(key1, "Value 1");
map.put(key2, "Value 2");
System.out.println(map); // Выведет обе пары: {key=Value 1, key=Value 2}
}
}
key1 и key2 — это разные объекты, даже если их строки одинаковы.
✨ Когда использовать?
1️⃣ Кэширование: если нужно различать объекты с одинаковыми данными.
2️⃣ Оптимизация: для низкоуровневой работы с объектами, где важна ссылка, а не значение.
3️⃣ Специфические задачи: при разработке компиляторов, интерпретаторов или для отслеживания уникальных объектов.
💡 Ограничение:
IdentityHashMap не гарантирует порядок элементов и редко используется в стандартных задачах. Это инструмент для узкоспециализированных случаев!#Java #IdentityHashMap
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤1
WeakHashMap — это коллекция, которая позволяет ключам удаляться из неё автоматически, если на них больше нет сильных ссылок.Если ключ в
WeakHashMap становится недостижимым (нет сильных ссылок), он удаляется сборщиком мусора.Это делает WeakHashMap полезной для реализации кэшей и других структур, где нужно избегать утечек памяти.
📌 Пример:
java
import java.util.WeakHashMap;
public class WeakHashMapExample {
public static void main(String[] args) {
WeakHashMap<Object, String> map = new WeakHashMap<>();
Object key = new Object();
map.put(key, "Value");
System.out.println("Before GC: " + map); // Ключ и значение есть
key = null; // Убираем сильную ссылку на объект
System.gc(); // Вызываем сборку мусора
System.out.println("After GC: " + map); // Ключ и значение исчезли
}
}
Пока объект-ключ доступен, пара ключ-значение остаётся в WeakHashMap.
Как только ключ становится недоступным, он автоматически удаляется сборщиком мусора.
✨ Когда использовать?
1️⃣ Кэширование: для хранения данных, которые можно восстановить, если они удалены.
2️⃣ Маппинг вспомогательных данных: например, привязка метаданных к объектам, где их удаление важно.
💡 Совет:
Не используйте WeakHashMap для данных, которые критически важны — сборщик мусора может удалить их в любой момент!
#Java #WeakHashMap
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🤷♂2❤1👎1🤩1
LinkedHashMap — это реализация Map, которая сохраняет порядок добавления элементов. Но что, если нужен порядок по использованию (LRU-кэш)? LinkedHashMap справится и с этим!Порядок добавления (по умолчанию):
java
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapExample {
public static void main(String[] args) {
Map<Integer, String> map = new LinkedHashMap<>();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
System.out.println(map); // {1=One, 2=Two, 3=Three}
}
}
Порядок использования:
Передайте accessOrder = true в конструктор.
java
import java.util.LinkedHashMap;
import java.util.Map;
public class LRUExample {
public static void main(String[] args) {
Map<Integer, String> map = new LinkedHashMap<>(16, 0.75f, true);
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
map.get(2); // Используем ключ 2
System.out.println(map); // {1=One, 3=Three, 2=Two}
}
}
Можно переопределить метод
removeEldestEntry() для автоматического удаления старых записей.
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, String> eldest) {
return size() > 3; // Удалять записи, если их больше 3
}
#Java #LinkedHashMap #LRU
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2
import java.util.*;
public class Quest {
private static Random rnd = new Random();
public static void main(String[] args) {
StringBuffer word = null;
switch(rnd.nextInt(2)) {
case 1: word = new StringBuffer('P');
case 2: word = new StringBuffer('G');
default: word = new StringBuffer('M');
}
word.append('a');
word.append('i');
word.append('n');
System.out.println(word);
}
}
👍3
😭15🎉3
Многопоточность позволяет выполнять несколько задач одновременно, что увеличивает производительность приложений и улучшает отзывчивость интерфейса.
Стандартный метод работы с потоками может быть сложным и запутанным.
CompletableFuture — более удобный и мощный инструмент, который упрощает асинхронное программирование.✍️ Пример: Выполнение задач параллельно с использованием
CompletableFuture
import java.util.concurrent.CompletableFuture;
public class AsyncExample {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
sleep(2000);
return "Результат задачи 1";
});
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
sleep(3000);
return "Результат задачи 2";
});
CompletableFuture<String> combined = task1.thenCombine(task2, (result1, result2) -> result1 + " & " + result2);
// Ожидаем завершения всех задач и получаем общий результат
combined.thenAccept(result -> {
long endTime = System.currentTimeMillis();
System.out.println("Общий результат: " + result);
System.out.println("Время выполнения: " + (endTime - startTime) + " мс");
});
combined.join(); // Дождёмся завершения наших задач
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
🔧 Что происходит в коде?
1️⃣ Мы запускаем две задачи, каждая из которых выполняется асинхронно.
2️⃣ Используем метод
thenCombine, чтобы объединить результаты двух задач.3️⃣ Когда обе задачи завершены, выводим общий результат и время выполнения.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2
Files.walkFileTree() из пакета java.nio.file позволяет рекурсивно обходить дерево каталогов и выполнять сложные операции. Это гибкий и удобный способ работать с файловой системой, включая чтение, обработку, копирование или удаление файлов.🔍 Как это работает?
1️⃣ Реализуется интерфейс
FileVisitor, который определяет действия для каждой операции.2️⃣ Можно обрабатывать файлы и директории на каждом этапе обхода.
📌 Пример: удаление дерева каталогов
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class WalkFileTreeExample {
public static void main(String[] args) throws IOException {
Path startPath = Paths.get("example_directory");
Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("Deleting file: " + file);
Files.delete(file); // Удаляем файл
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
System.out.println("Deleting directory: " + dir);
Files.delete(dir); // Удаляем директорию после удаления её содержимого
return FileVisitResult.CONTINUE;
}
});
}
}
🔗 Ключевые методы
FileVisitor:visitFile() — вызывается для каждого файла.postVisitDirectory() — вызывается после обхода содержимого директории.preVisitDirectory() — вызывается перед входом в директорию.visitFileFailed() — обрабатывает ошибки доступа.✨ Когда использовать?
1️⃣ Для удаления, копирования или архивирования файлов/папок.
2️⃣ Для поиска файлов по сложным критериям.
3️⃣ Для выполнения массовых операций с файлами (изменение атрибутов, анализ).
💡 Совет: Используйте
SimpleFileVisitor, чтобы переопределять только нужные методы, а не реализовать весь интерфейс FileVisitor.#Java #Files #FileVisitor
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
С появлением Java 12
Collectors.teeing() стал удобным инструментом для объединения двух независимых операций над потоком. Этот коллектор позволяет выполнять две разные операции над данными и объединять их результат с помощью функции-объединителя.🔍 Как это работает?
1️⃣ Указываем два коллектора для операций.
2️⃣ Задаём функцию, которая объединит результаты этих операций.
📌 Пример: Найдём сумму и среднее списка чисел.
import java.util.List;
import java.util.stream.Collectors;
public class TeeingExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
var result = numbers.stream().collect(
Collectors.teeing(
Collectors.summingInt(Integer::intValue), // Первая операция: сумма
Collectors.averagingInt(Integer::intValue), // Вторая операция: среднее
(sum, avg) -> "Sum: " + sum + ", Average: " + avg // Объединение результатов
)
);
System.out.println(result); // Вывод: Sum: 15, Average: 3.0
}
}
Это позволяет избавиться от многократного прохода по потоку, а код становится компактным и читаемым.
✨ Когда использовать?
1️⃣ Для выполнения нескольких независимых операций над данными потока.
2️⃣ Если нужно объединить результаты этих операций.
💡 Совет:
Collectors.teeing() особенно полезен, когда результаты независимых операций логически связаны. Например, для расчёта статистики или агрегации данных.#Java #Streams #Collectors #teeing
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2
Base64 — это способ представления данных в текстовом формате, который можно безопасно передавать через сеть и использовать в текстовых форматах. В Java для работы с Base64 используется встроенный класс
java.util.Base64. 🔍 Кодирование строки в Base64:
import java.util.Base64;
public class Base64Example {
public static void main(String[] args) {
String original = "Hello, Java!";
String encoded = Base64.getEncoder().encodeToString(original.getBytes());
System.out.println("Encoded: " + encoded); // Вывод: SGVsbG8sIEphdmEh
}
}
🔗 Декодирование строки из Base64:
String encoded = "SGVsbG8sIEphdmEh";
String decoded = new String(Base64.getDecoder().decode(encoded));
System.out.println("Decoded: " + decoded); // Вывод: Hello, Java!
✨ Варианты кодировщиков:
1️⃣
Base64.getEncoder() — стандартный кодировщик. 2️⃣
Base64.getUrlEncoder() — для URL и имён файлов (без символов + и /). 3️⃣
Base64.getMimeEncoder() — для MIME-форматов (разбивает строки на блоки по 76 символов). 💡 Когда использовать?
1️⃣ При передаче данных в текстовом виде (например, JSON или бинарные файлы).
2️⃣ Для работы с авторизацией (например, токены в Basic Auth).
3️⃣ Взаимодействие с API, использующими кодировку Base64.
#Java #Base64
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1
Optional.orElseGet() — это метод, который позволяет задать значение по умолчанию, вызывая поставщик (Supplier) только тогда, когда Optional пуст.Если значение присутствует, возвращается оно.
Если значение отсутствует, вызывается
Supplier, который возвращает значение по умолчанию.📌 Пример:
import java.util.Optional;
public class OptionalOrElseGetExample {
public static void main(String[] args) {
String defaultValue = "Default Value";
// Пример с orElse
System.out.println("Using orElse:");
System.out.println(getValue().orElse(expensiveOperation(defaultValue)));
// Пример с orElseGet
System.out.println("Using orElseGet:");
System.out.println(getValue().orElseGet(() -> expensiveOperation(defaultValue)));
}
private static Optional<String> getValue() {
return Optional.empty(); // Эмулируем пустой Optional
}
private static String expensiveOperation(String input) {
System.out.println("Executing expensive operation...");
return input;
}
}
🔗 Ключевая разница между orElse и orElseGet:
✔️
orElse() всегда вычисляет значение по умолчанию, даже если оно не нужно.✔️
orElseGet() вызывает логику только при необходимости, что экономит ресурсы.💡 Совет:
Используйте orElseGet, если значение по умолчанию требует сложных вычислений или вызовов. Это сделает ваш код эффективнее.
#Java #Optional #orElse #orElseGet
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1🔥1👏1
public class Quest {
public static void main(String[] args) {
System.out.println("a\".length() + \"b".length());
}
}👍1
👍7❤1🎉1