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

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

✍️По всем вопросам: @Pascal4eg
Download Telegram
public class Quest {
public static void main(String[] args) {
System.out.println(calc(10, 5));
}

private static int calc(int i, int j) {
int result = i + j;
return result;

result = i - j;
return result;
}
}
3
Что выведет код?
Anonymous Quiz
32%
15
9%
5
59%
ошибка компиляции
👍7🎉3
🌱 Spring Boot Actuator — это подмножество библиотек Spring Boot, которое предоставляет функции мониторинга и управления работающим приложением. Он добавляет несколько полезных средств для разработки, диагностики и управления приложениями, включая метрики, проверку состояния, аудит и прочее.

Метрики (Metrics)
Actuator собирает информацию о работе приложения, такую как использование памяти, процессора, количество запросов и их время обработки. Метрики могут быть доступны через конечные точки или интегрированы с системами мониторинга, такими как Prometheus, Graphite и другие.

Конечные точки (Endpoints)
Actuator предоставляет несколько конечных точек, которые можно использовать для получения информации о состоянии приложения. Некоторые из них:
/actuator/health - возвращает информацию о состоянии приложения.
/actuator/info - предоставляет общую информацию о приложении.
/actuator/metrics - возвращает метрики приложения.
/actuator/env - показывает текущее состояние окружения, включая системные свойства и переменные окружения.

Проверка состояния (Health Checks)
Actuator может проверять состояние различных компонентов приложения (например, баз данных, внешних сервисов и т.д.) и предоставлять общую оценку состояния.

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

HTTP-трейс (HTTP Tracing)
Возможность отслеживания всех входящих HTTP-запросов и ответов.

Для подключения нужно добавить зависимость:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

и добавить в файл конфигурации:

management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always


#java #actuator #health
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🥱31
⌨️ Литералы — это явно заданные значения в коде программы — константы определенного типа, которые находятся в коде в момент запуска.


class Test {
int a = 0b1101010110;
public static void main(String[] args) {
System.out.println("Hello world!");
}
}


В этом классе “Hello world!” — литерал.

Переменная a - тоже литерал.

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

#java #literals
Please open Telegram to view this post
VIEW IN TELEGRAM
👍131
⌨️ Семафор (Semaphore) - класс из пакета java.util.concurrent, предназначенный для управления доступом к общим ресурсам в многопоточных приложениях. Он позволяет ограничить количество потоков, которые могут одновременно использовать определенный ресурс.

Семафор управляет набором разрешений, и поток может запросить или освободить разрешение, тем самым контролируя доступ к общим ресурсам.

Конструктор:
Semaphore(int permits) - создает семафор с указанным числом разрешений.

Методы для получения разрешений:

void acquire() - запрашивает одно разрешение. Если разрешение недоступно, поток блокируется до тех пор, пока разрешение не станет доступным.

void acquire(int permits) - запрашивает указанное количество разрешений.

boolean tryAcquire() - запрашивает одно разрешение, если оно доступно, не блокируя поток. Возвращает true, если разрешение получено, и false в противном случае.

boolean tryAcquire(long timeout, TimeUnit unit) - запрашивает одно разрешение, если оно доступно в течение указанного времени. Возвращает true, если разрешение получено, и false в противном случае.

Методы для освобождения разрешений:

void release() - освобождает одно разрешение, увеличивая внутренний счетчик разрешений.

void release(int permits) - освобождает указанное количество разрешений.

Пример:

import java.util.concurrent.Semaphore;

public class SemaphoreExample {
private static final int MAX_CONCURRENT_THREADS = 3;
private static final Semaphore semaphore = new Semaphore(MAX_CONCURRENT_THREADS);

public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(new Worker(i)).start();
}
}

static class Worker implements Runnable {
private final int id;

Worker(int id) {
this.id = id;
}

@Override
public void run() {
try {
System.out.println("Thread " + id + " is waiting for a permit.");
semaphore.acquire();
System.out.println("Thread " + id + " acquired a permit.");

// Simulate some work with a sleep
Thread.sleep(2000);

System.out.println("Thread " + id + " releasing a permit.");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


В этом примере создается семафор, который позволяет одновременно работать трем потокам. Остальные потоки будут ждать, пока не освободится разрешение. Каждый поток выполняет работу (симулированную с помощью Thread.sleep(2000)), после чего освобождает разрешение, позволяя другому ожидающему потоку приступить к работе.

#java #semaphore
Please open Telegram to view this post
VIEW IN TELEGRAM
👍162
public class Quest {
public final int value = 4;
public void doIt() {
int value = 6;
Runnable r = new Runnable() {
public final int value = 8;
public void run() {
int value = 10;
System.out.println(this.value);
}
};
r.run();
}
public static void main(String[] args) {
new Quest().doIt();
}
}

#java #quest
Что выведет код?
Anonymous Quiz
27%
4
8%
6
37%
8
28%
10
🎉8
⌨️ Какая основная разница между String, StringBuffer, StringBuilder?

Класс String является неизменяемым (immutable) - модифицировать объект такого класса нельзя, можно лишь заменить его созданием нового экземпляра.

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

Класс StringBuilder был добавлен в Java 5 и он во всем идентичен классу StringBuffer за исключением того, что он не синхронизирован и поэтому его методы выполняются значительно быстрей.

#java #String #StringBuffer #StringBuilder
Please open Telegram to view this post
VIEW IN TELEGRAM
👍113
🍓31👍42❤‍🔥2
🖥 Интересно про то как у нас в Java 23 должна была быть, но не будет, интерполяция строк (String Templates)

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

Это должно было выглядеть так:
String name = "Melissa";
System.out.println("Hello, \{name}!");
// Hello, Melissa!

Habr

#java #StringTemplates
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍1
⌨️ PriorityQueue — это реализация структуры данных очередь с приоритетом, которая упорядочивает элементы по их естественному порядку или по заданному компаратору. Она представляет собой часть коллекции Java Collections Framework и находится в пакете java.util.

В отличие от Queue, элементы PriorityQueue не упорядочены по времени их добавления, а по приоритету.

Основные методы:

add(E e) - добавляет элемент в очередь.

remove() - удаляет и возвращает элемент с наивысшим приоритетом. Если очередь пуста, генерируется исключение NoSuchElementException.

poll() - удаляет и возвращает элемент с наивысшим приоритетом. Если очередь пуста, возвращает null.

peek() - возвращает, но не удаляет элемент с наивысшим приоритетом. Если очередь пуста, возвращает null.

element() - возвращает, но не удаляет элемент с наивысшим приоритетом. Если очередь пуста, генерируется исключение NoSuchElementException.

Пример:

class Task implements Comparable<Task> {
String name;
Integer priority;

public Task(String name, Integer priority) {
this.name = name;
this.priority = priority;
}

@Override
public int compareTo(@NotNull Task o) {
return priority - o.priority;
}
}

public class Test {
public static void main(String[] args) {
PriorityQueue<Task> pq = new PriorityQueue<>();

pq.add(new Task("Task1", 1));
pq.add(new Task("Task5", 5));
pq.add(new Task("Task2", 2));
pq.add(new Task("Task4", 4));
pq.add(new Task("Task3", 3));

while (!pq.isEmpty()) {
System.out.println(pq.poll().name);
// Выведет: Task1, Task2, Task3, Task4, Task5
}
}
}


#java #PriorityQueue
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
⌨️ Особенности класса String

✔️ Это неизменяемый (immutable) и финализированный тип данных;

✔️ Строки-литералы, интернированные объекты класса String JVM хранит в пуле строк;

✔️ Объект класса String можно получить, используя двойные кавычки;

✔️ Можно использовать оператор + для конкатенации строк;

✔️ Начиная с Java 7 строки можно использовать в конструкции switch.

#java #string
Please open Telegram to view this post
VIEW IN TELEGRAM
👍91😁1
⌨️ Почему String неизменяемый класс?

Есть несколько преимуществ в неизменности строк:

✔️ Пул строк возможен только потому, что строка неизменяемая, таким образом виртуальная машина сохраняет больше свободного места в Heap, поскольку разные строковые переменные указывают на одну и ту же переменную в пуле. Если бы строка была изменяемой, то интернирование строк не было бы возможным, потому что изменение значения одной переменной отразилось бы также и на остальных переменных, ссылающихся на эту строку.

✔️ Если строка будет изменяемой, тогда это станет серьезной угрозой безопасности приложения. Например, имя пользователя базы данных и пароль передаются строкой для получения соединения с базой данных и в программировании сокетов реквизиты хоста и порта передаются строкой. Так как строка неизменяемая, её значение не может быть изменено, в противном случае злоумышленник может изменить значение ссылки и вызвать проблемы в безопасности приложения.

✔️ Неизменяемость позволяет избежать синхронизации: строки безопасны для многопоточности и один экземпляр строки может быть совместно использован различными потоками.

✔️ Строки используются classloader и неизменность обеспечивает правильность загрузки класса.

✔️ Поскольку строка неизменяемая, её hashCode() кэшируется в момент создания и нет необходимости рассчитывать его снова. Это делает строку отличным кандидатом для ключа в HashMap т.к. его обработка происходит быстрее.

#java #string #immutable
Please open Telegram to view this post
VIEW IN TELEGRAM
👍171
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Quest {
public static void main(String[] args) {
List<String> list = Stream.of("Pizza", "Sushi", "Pasta", "Sushi", "Pizza")
.sequential()
.filter(new TreeSet<>()::add)
.collect(Collectors.toList());
System.out.println(list);
}
}
4👏2😐2😭2😡1
⌨️ Неизменяемые коллекции

Для получения неизменяемого варианта коллекции, в классе Collections есть соответствующие методы:

unmodifiableCollection
unmodifiableSequencedCollection
unmodifiableSet
unmodifiableSequencedSet
unmodifiableSortedSet
unmodifiableNavigableSet
unmodifiableList
unmodifiableMap
unmodifiableSequencedMap
unmodifiableSortedMap
unmodifiableNavigableMap

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

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


List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
List<String> unmodifiableList = Collections.unmodifiableList(list);
// Попытка изменить unmodifiableList приведет к UnsupportedOperationException
// unmodifiableList.remove("B");


#java #collections #immutable #unmodifiable
Please open Telegram to view this post
VIEW IN TELEGRAM
👌6👍4🔥2
😁19👍4🤣4💔2🙈1
Stream

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

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

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

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


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

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

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

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

Терминальные операции
Терминальные операции могут проходить через поток для получения результата или побочного эффекта.

📌 После выполнения терминальной операции, потоковый конвейер считается использованным и больше не может использоваться.

Терминальные операции:
forEach()
forEachOrdered()
toArray()
reduce()
collect()
min()
max()
count()
anyMatch()
allMatch()
noneMatch()
findFirst()
findAny()


Каждая из этих операций инициирует выполнение всех промежуточных операций.
👍182🔥1👏1
🧩 Комбинирование предикатов

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

Принимает на вход значение, проверяет состояние и возвращает boolean значение в качестве результата.

Предикаты можно комбинировать между собой и в результате получать составные условия.

У предиката есть 3 default метода для составления условия. Имена методов говорящие: and(), or(), negate()
👍8🔥2
⌨️ Что такое класс Object? Какие в нем есть методы?

Object это базовый класс для всех остальных объектов в Java. Любой класс наследуется от Object и, соответственно, наследуют его методы:

public boolean equals(Object obj) – служит для сравнения объектов по значению;

int hashCode() – возвращает hash код для объекта;

String toString() – возвращает строковое представление объекта;

Class getClass() – возвращает класс объекта во время выполнения;

protected Object clone() – создает и возвращает копию объекта;

void notify() – возобновляет поток, ожидающий монитор;

void notifyAll() – возобновляет все потоки, ожидающие монитор;

void wait() – остановка вызвавшего метод потока до момента пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

void wait(long timeout) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

void wait(long timeout, int nanos) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

protected void finalize() – может вызываться сборщиком мусора в момент удаления объекта при сборке мусора.

#java #Object #methods
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥2🥱1