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

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

✍️По всем вопросам: @Pascal4eg
Download Telegram
🖥 Оптимистичная и пессимистичная блокировка в базах данных

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

Алгоритм:
1️⃣ Чтение данных.
2️⃣ Обновление данных в памяти.
3️⃣ Попытка записи изменений с проверкой версии или временной метки.
4️⃣ Если данные были изменены другим процессом, транзакция откатывается и повторяется.

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

update table set field1='data1', field2='data2', version=<version>+1 where id=<id> and version=<version>

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

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

Алгоритм:
1️⃣ Чтение данных с блокировкой.
2️⃣ Обновление данных.
3️⃣ Запись изменений.
4️⃣ Снятие блокировки после завершения транзакции.

Как пример, может быть использован запрос SELECT ... FOR UPDATE для блокировки строк при чтении.

#java #database #optimistic #pessimistic #locking
Please open Telegram to view this post
VIEW IN TELEGRAM
👍54
⌨️ Вложенные классы. Когда применяются

Класс называется вложенным (Nested class), если он определен внутри другого класса. Вложенный класс должен создаваться только для того, чтобы обслуживать обрамляющий его класс. Если вложенный класс оказывается полезен в каком-либо ином контексте, он должен стать классом верхнего уровня. Вложенные классы имеют доступ ко всем (в том числе приватным) полям и методам внешнего класса, но не наоборот. Из-за этого разрешения использование вложенных классов приводит к некоторому нарушению инкапсуляции.

Существуют четыре категории вложенных классов:

1️⃣ Static nested class (Статический вложенный класс);
2️⃣ Member inner class (Простой внутренний класс);
3️⃣ Local inner class (Локальный класс);
4️⃣ Anonymous inner class (Анонимный класс).

Такие категории классов, за исключением первого, также называют внутренними (Inner class). Внутренние классы ассоциируются не с внешним классом, а с экземпляром внешнего.

Каждая из категорий имеет рекомендации по своему применению. Если вложенный класс должен быть виден за пределами одного метода или он слишком длинный для того, чтобы его можно было удобно разместить в границах одного метода и если каждому экземпляру такого класса необходима ссылка на включающий его экземпляр, то используется нестатический внутренний класс. В случае, если ссылка на обрамляющий класс не требуется - лучше сделать такой класс статическим. Если класс необходим только внутри какого-то метода и требуется создавать экземпляры этого класса только в этом методе, то используется локальный класс. А, если к тому же применение класса сводится к использованию лишь в одном месте и уже существует тип, характеризующий этот класс, то рекомендуется делать его анонимным классом.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🔥1👏1
class Base {
public String className = "Base";
}

class Derived extends Base {
private String className = "Derived";
}

public class Quest {
public static void main(String[] args) {
System.out.println(new Derived().className);
}
}
Что выведет код?
Anonymous Quiz
30%
Base
39%
Derived
32%
ошибка компиляции
👍2🎉21👏1
⌨️ Что такое «статический класс»?

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

Это означает, что он связан с внешним классом, но при этом не имеет доступа к нестатическим членам внешнего класса, если только они не предоставляются явно.

Экземпляр статического вложенного класса создается без необходимости создания экземпляра внешнего класса. Это отличается от обычных вложенных (внутренних) классов, которые требуют создания экземпляра внешнего класса.


public class Outer {
private static String staticMember = "Static Member";
private String instanceMember = "Instance Member";

// Статический вложенный класс
public static class StaticNested {
public void display() {
// Доступ к статическому члену внешнего класса
System.out.println(staticMember);

// Нельзя напрямую обращаться к нестатическому члену внешнего класса
// System.out.println(instanceMember); // Ошибка компиляции
}
}

public static void main(String[] args) {
// Создание экземпляра статического вложенного класса
Outer.StaticNested nestedObject = new Outer.StaticNested();
nestedObject.display();
}
}


#java #static #class
Please open Telegram to view this post
VIEW IN TELEGRAM
👍101🔥1👏1
class A {
static class B {
static String C = "NOT TO BE";
}
static Z B = new Z();
}

class Z {
String C = "TO BE";
}

public class Quest {
public static void main(String[] args) {
System.out.println(A.B.C);
}
}


#java #quest
👍1
Что выведет код?
Anonymous Quiz
17%
TO BE
34%
NOT TO BE
49%
ошибка компиляции
🎉2❤‍🔥11🤡1
Паттерн MVC (Model-View-Controller) — это архитектурный шаблон, используемый для разделения приложения на три основных компонента: модель, представление и контроллер. Это помогает улучшить организацию кода, облегчить его поддержку и тестирование.

Модель (Model) предоставляет данные и реагирует на команды контроллера, изменяя своё состояние.

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

Контроллер (Controller) интерпретирует действия пользователя, оповещая модель о необходимости изменений.

Основная цель применения этой концепции состоит в отделении бизнес-логики (модели) от её визуализации (представления, вида). За счёт такого разделения повышается возможность повторного использования кода. Наиболее полезно применение данной концепции в тех случаях, когда пользователь должен видеть те же самые данные одновременно в различных контекстах и/или с различных точек зрения. В частности, выполняются следующие задачи:

1️⃣ К одной модели можно присоединить несколько видов, при этом не затрагивая реализацию модели. Например, некоторые данные могут быть одновременно представлены в виде электронной таблицы, гистограммы и круговой диаграммы;

2️⃣ Не затрагивая реализацию видов, можно изменить реакции на действия пользователя (нажатие мышью на кнопке, ввод данных) — для этого достаточно использовать другой контроллер;

3️⃣ Ряд разработчиков специализируется только в одной из областей: либо разрабатывают графический интерфейс, либо разрабатывают бизнес-логику. Поэтому возможно добиться того, что программисты, занимающиеся разработкой бизнес-логики (модели), вообще не будут осведомлены о том, какое представление будет использоваться.

#java #pattern #MVC
👍42🔥1
⌨️ Функциональный интерфейс Consumer является частью пакета java.util.function и предназначен для представления операции, которая принимает один входной аргумент и не возвращает результата. Этот интерфейс используется для операций, выполняемых с объектом, но не возвращающих значения, таких как вывод данных, модификация объектов и выполнение побочных эффектов.

Интерфейс Consumer аннотирован @FunctionalInterface, что означает, что он предназначен для использования с лямбда-выражениями и содержит ровно один абстрактный метод:

void accept(T t);

Выполняет операцию над переданным аргументом типа T.

Пример:

List<String> strings = Arrays.asList("a", "b", "c");
Consumer<String> printer = System.out::println;
strings.forEach(printer);
// a
// b
// c


Еще один:

List<String> list = Arrays.asList("a", "b", "c");
Consumer<List<String>> listModifier = l -> l.add("d");
listModifier.accept(list);
System.out.println(list); // [a, b, c, d]


#java #consumer
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤‍🔥1👨‍💻1
🤣20👍3🔥2👏1😁1
This media is not supported in your browser
VIEW IN TELEGRAM
Юзеры не знают своих героев...
28👍9😁9🔥4💯2👏1🤣1
⌨️ Что такое «локальный класс»? Каковы его особенности?

Local inner class (Локальный класс) - это вложенный класс, который может быть декларирован в любом блоке, в котором разрешается декларировать переменные. Как и простые внутренние классы (Member inner class) локальные классы имеют имена и могут использоваться многократно. Как и анонимные классы, они имеют окружающий их экземпляр только тогда, когда применяются в нестатическом контексте.

Локальные классы имеют следующие особенности:

Видны только в пределах блока, в котором объявлены;

Не могут быть объявлены как private/public/protected или static;

Не могут иметь внутри себя статических объявлений методов и классов, но могут иметь финальные статические поля, проинициализированные константой;

Имеют доступ к полям и методам обрамляющего класса;

Могут обращаться к локальным переменным и параметрам метода.


public class OuterClass {

void someMethod() {
int localVar = 10;

// Локальный класс внутри метода
class LocalClass {
void display() {
// Локальный класс имеет доступ к переменным метода
System.out.println("Local variable: " + localVar);
}
}

LocalClass local = new LocalClass();
local.display();
}

public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.someMethod();
}
}


#java #local #inner #class
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥21
⌨️ Какие существуют особенности использования вложенных классов: статических и внутренних? В чем заключается разница между ними?

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

Для создания объекта статического вложенного класса объект внешнего класса не требуется.

Из объекта статического вложенного класса нельзя обращаться к не статическим членам обрамляющего класса напрямую, а только через ссылку на экземпляр внешнего класса.

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

В объекте обычного вложенного класса хранится ссылка на объект внешнего класса. Внутри статической такой ссылки нет. Доступ к экземпляру обрамляющего класса осуществляется через указание .this после его имени. Например: Outer.this.

#java #nested #static #class
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1👏1👨‍💻1
⌨️ Что такое «анонимные классы»? Где они применяются?

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

Анонимные классы имеют несколько ограничений:

✔️ Их использование разрешено только в одном месте программы - месте его создания;

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

✔️ Реализует лишь методы своего интерфейса или суперкласса, т.е. не может объявлять каких-либо новых методов, так как для доступа к ним нет поименованного типа.

Анонимные классы обычно применяются для:

✔️ создания объекта функции (function object), например, реализация интерфейса Comparator;

✔️ создания объекта процесса (process object), такого как экземпляры классов Thread, Runnable и подобных;

✔️ в статическом методе генерации;

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

#java #abstract #class
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61🔥1👏1
public class Quest {
public static void main(String[] args) {
System.out.print(condition1() && condition2());
}

private static boolean condition1() {
System.out.print(1);
return false;
}

private static boolean condition2() {
System.out.print(2);
return true;
}
}
🔥31
Что выведет код?
Anonymous Quiz
55%
1false
38%
12false
7%
21false
3🎉1😍1
⌨️ DateTimeFormatter — это класс в Java, который используется для форматирования и парсинга дат и времени. Он предоставляет различные методы для преобразования объектов даты и времени в строку и наоборот. Этот класс является частью пакета java.time.format и был введен в Java 8 в рамках новой Date and Time API.

DateTimeFormatter содержит предопределенные форматы, такие как ISO_LOCAL_DATE, ISO_LOCAL_TIME, ISO_LOCAL_DATE_TIME, BASIC_ISO_DATE и другие. Так же, DateTimeFormatter поддерживает создание пользовательских форматов с использованием шаблонов.

Форматирование даты и времени:

LocalDateTime now = LocalDateTime.now();

// Использование предопределенного формата
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
String formattedDate = now.format(formatter);
System.out.println("ISO_LOCAL_DATE_TIME: " + formattedDate);
// ISO_LOCAL_DATE_TIME: 2024-06-20T21:46:43.584659

// Использование пользовательского формата
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String customFormattedDate = now.format(customFormatter);
System.out.println("Custom format: " + customFormattedDate);
// Custom format: 20-06-2024 21:46:43


Парсинг строки в дату и время:

String dateStr = "2024-06-20T15:30:00";

// Использование предопределенного формата
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);
System.out.println("Parsed date (ISO_LOCAL_DATE_TIME): " + dateTime);
// Parsed date (ISO_LOCAL_DATE_TIME): 2024-06-20T15:30

// Использование пользовательского формата
String customDateStr = "20.06.2024 15:30:00";
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
LocalDateTime customDateTime = LocalDateTime.parse(customDateStr, customFormatter);
System.out.println("Parsed date (custom format): " + customDateTime);
// Parsed date (custom format): 2024-06-20T15:30


#java #DateTimeFormatter
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥5👍2🔥21
⌨️ Проброс исключений

Иногда возникает необходимость передать исключение дальше по стеку вызовов, чтобы оно было обработано на более высоком уровне. Для этого можно использовать ключевое слово throws в сигнатуре метода и не перехватывать исключение в блоке catch, либо пробросить исключение дальше внутри блока catch.


public void someMethod() throws IOException {
try {
// код, который может выбросить IOException
} catch (IOException e) {
// возможно, выполнить какую-то обработку
throw e; // проброс исключения дальше
}
}


#java #throw #throws
Please open Telegram to view this post
VIEW IN TELEGRAM
5
public class Quest {
public static void main(String[] args) {
int i=0;
label1: System.out.print(i++);
if (i < 2) {
goto label1;
}
}
}


#java #quest
😁8
Что выведет код?
Anonymous Quiz
40%
012
11%
123
48%
ошибка компиляции
4👏2🎉1