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

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

✍️По всем вопросам: @Pascal4eg
Download Telegram
⌨️ Использование аннотаций. Аннотации позволяют добавлять метаданные к вашему коду, что может быть полезно для документирования, тестирования и других целей. Вот пример использования аннотации:

import java.lang.annotation.*;

// Создание аннотации
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MethodInfo {
String author() default "unknown";
String date();
int revision() default 1;
String comments();
}

public class Example {
// Использование аннотации
@MethodInfo(author = "John Doe", date = "2022-08-15", comments = "Example method")
public void performAction() {
// Реализация метода
}
}


В этом примере создается аннотация MethodInfo с параметрами author, date, revision и comments. Затем аннотация применяется к методу performAction. Таким образом, аннотации могут использоваться для предоставления дополнительной информации о вашем коде, что может быть полезно при разработке, тестировании и поддержке проекта.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍31💯1
Методы и конструкторы в enum

Перечисления (enum) — это классы Java, определяющие наборы констант. Самый простой enum выглядит так:


public enum Vehicle { CAR, BUS, BICYCLE, SCOOTER }


Но на самом деле, enum в Java обладают гораздо более широким функционалом. Они поддерживают поля, методы, интерфейсы и т.д. Они также Comparable и Serializable и могут имплементировать все методы объекта.
Для наглядности давайте создадим enum Animal и присвоим каждому элементу цвет:

public enum Animal {
DOG("black"),
CAT("white"),
RAT("gray");

private final String color;
Animal(String color){
this.color = color;
}
public String getColor(){
return color;
}
}


Теперь мы можем выполнить перебор элементов массива с помощью статического метода values():

public class Main {
public static void main(String[] args) {
for (Animal a : Animal.values()) {
System.out.println(a.name() + " - " + a.getColor());
}
}
}


Мы получим следующий результат:

DOG - black
CAT - white
RAT - gray


Каждой константе можно присвоить разное поведение при выполнении определенного метода. Например, можно сделать основной метод абстрактным и переопределить его в каждой константе:

public enum Operation {
PLUS { double evaluate(double x, double y) { return x + y; } },
MINUS { double evaluate(double x, double y) { return x - y; } },
abstract double evaluate(double x, double y);
}


Всё это обеспечивает удобную работу с перечислениями в Java.
👍272🔥2🥰2👏1
JSON – невероятно удобный и полезный формат для хранения и обмена данными. Java полностью поддерживает его.

Сериализовать данные можно так:

JSONObject author = new JSONObject();
author.put("name", "J. K. Rowling");
author.put("numberOfBooks", 22);

JSONArray books = new JSONArray();
books.put("Harry Potter and the Philosopher's Stone");
books.put("Harry Potter and the Chamber of Secrets");
books.put("Harry Potter and the Prisoner of Azkaban");

author.put("books", books);
System.out.print(author);


Получится вот такая JSON-строка:

{"books":["Harry Potter and the Philosopher's Stone","Harry Potter and the Chamber of Secrets","Harry Potter and the Prisoner of Azkaban"],"name":"J. K. Rowling","numberOfBooks":22}


Десериализация на Java выглядит примерно так:

JSONObject author = new JSONObject(serializedString);
System.out.println("name: " + author.get("name"));
System.out.println("numberOfBooks: " + author.get("numberOfBooks"));

JSONArray books = (JSONArray) author.get("books");
Iterator<Object> i = books.iterator();
System.out.println("books:");
while (i.hasNext()) {
System.out.println(i.next());
}


Нужно добавить зависимость:

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
👍16🔥64
Array vs ArrayList

Выбор между Array и ArrayList зависит от специфики задачи на Java, которую требуется решить.

📌Помните о следующих особенностях этих типов:

• Array имеет фиксированный размер и память для него выделяется в момент объявления, а размер ArrayLists может динамически изменяться.

• Массивы Java работают гораздо быстрее, а в ArrayList намного проще добавлять/удалять элементы.

• При работе с Array велика вероятность получить ошибку ArrayIndexOutOfBoundsException.

• У ArrayList только одно измерение, а вот массивы Java могут быть многомерными.

import java.util.ArrayList;

public class arrayVsArrayList {

public static void main(String[] args) {

// объявление Array
int[] myArray = new int[6];

// обращение к несуществующему индексу
myArray[7]= 10; // ArrayIndexOutOfBoundsException

// объявление ArrayList
ArrayList<Integer> myArrayList = new ArrayList<>();

// простое добавление и удаление элементов
myArrayList.add(1);
myArrayList.add(2);
myArrayList.add(3);
myArrayList.add(4);
myArrayList.add(5);
myArrayList.remove(0);

// получение элементов ArrayList
for(int i = 0; i < myArrayList.size(); i++) {
System.out.println("Element: " + myArrayList.get(i));
}

// многомерный Array
int[][][] multiArray = new int [3][3][3];
}
}
👍161👎1🔥1🤗1
⌨️ Фишка: Создание итератора для пользовательского класса.

Код:
import java.util.Iterator;

public class CustomClass implements Iterable<String> {
private String[] elements;

public CustomClass(String[] elements) {
this.elements = elements;
}

@Override
public Iterator<String> iterator() {
return new CustomIterator();
}

private class CustomIterator implements Iterator<String> {
private int index = 0;

@Override
public boolean hasNext() {
return index < elements.length;
}

@Override
public String next() {
if (this.hasNext()) {
return elements[index++];
} else {
throw new NoSuchElementException();
}
}
}

public static void main(String[] args) {
String[] arr = {"one", "two", "three"};
CustomClass customClass = new CustomClass(arr);

for (String element : customClass) {
System.out.println(element);
}
}
}


💁‍♂️ Этот код позволяет создать итератор для пользовательского класса CustomClass. Итератор позволяет перебирать элементы массива elements и использовать их в цикле for-each.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍122🔥1🤝1
⌨️ Использование интерфейсов для множественного наследования

// Создание интерфейсов
interface Printable {
void print();
}

interface Showable {
void show();
}

// Реализация интерфейсов в классе
class MyClass implements Printable, Showable {
public void print() {
System.out.println("Printing...");
}

public void show() {
System.out.println("Showing...");
}
}

public class Main {
public static void main(String[] args) {
// Создание объекта класса MyClass
MyClass obj = new MyClass();
obj.print();
obj.show();
}
}


🔎 В данном коде используются интерфейсы для реализации множественного наследования. Класс MyClass реализует два интерфейса Printable и Showable, и поэтому класс может использовать методы, определенные в обоих интерфейсах. Это позволяет создавать гибкие и модульные программы, используя механизм интерфейсов в Java.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥4👨‍💻21
⌨️ Использование StringBuilder для эффективной конкатенации строк:

public class StringBuilderExample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append("строка ").append(i).append("\n");
}
String result = sb.toString();
System.out.println(result);
}
}


📌 В этом примере используется StringBuilder для объединения 10 строк "строка i" в одну строку. Это более эффективно, чем использование оператора "+" или String.concat(), особенно при большом количестве операций конкатенации строк.

StringBuilder предоставляет изменяемую последовательность символов и позволяет выполнять эффективные операции вставки, удаления и конкатенации строк.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥31
💻 Как полезную фишку на Java можно рассмотреть использование лямбда-выражений для упрощения написания анонимных классов. Например, использование лямбда-выражения для выполнения операции над элементами коллекции:

import java.util.Arrays;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// Использование лямбда-выражения для вывода каждого элемента в консоль
numbers.forEach(n -> System.out.println(n));

// Использование лямбда-выражения для умножения каждого элемента на 2
numbers.replaceAll(n -> n * 2);
System.out.println(numbers); // Вывод: [2, 4, 6, 8, 10]
}
}


🔝 Использование лямбда-выражений делает код более компактным и удобочитаемым, особенно при работе с коллекциями и функциональными интерфейсами.
👍17🔥42🥰2
⌨️ Параллельное выполнение задач с использованием ExecutorService

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

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
public static void main(String[] args) {
// Создание пула потоков
ExecutorService executor = Executors.newFixedThreadPool(5);

// Подача задач на выполнение
for (int i = 0; i < 10; i++) {
executor.execute(new Task(i));
}

// Остановка пула потоков после выполнения задач
executor.shutdown();
}

static class Task implements Runnable {
private int taskId;

public Task(int taskId) {
this.taskId = taskId;
}

@Override
public void run() {
System.out.println("Выполнение задачи " + taskId + " в потоке " +
Thread.currentThread().getName());
}
}
}


🧑‍💻Этот код создает пул из 5 потоков и подает на выполнение 10 задач. Каждая задача выводит свой идентификатор и имя потока, в котором она выполняется. После выполнения всех задач пул потоков останавливается.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥53👨‍💻1
Did anyone say Java?
👍42🤣7🔥5😁3🤩2💯21
⌨️ Использование интерфейса Callable вместе с классом Future для выполнения асинхронных задач и получения их результата:

ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(1);
Future<Integer> futureResult = executor.submit(() -> {
// Выполнение сложной вычислительной задачи
int result = 0;
for (int i = 0; i < 100; i++) {
result += i;
Thread.sleep(100);
}
return result;
});

// Другие действия, выполняемые параллельно

// Ожидание завершения асинхронной задачи и получение результата
Integer result = futureResult.get();
System.out.println("Результат: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
if (executor != null) executor.shutdown();
}

➡️В данном примере создается пул потоков размером 1, затем создается асинхронная задача с использованием интерфейса Callable, который возвращает результат типа Integer. Задача выполняет сложное вычисление с задержкой в 100 миллисекунд каждую итерацию.

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

Метод get() вызывается для ожидания завершения задачи и получения результата. Если задача еще не завершилась, вызов этого метода блокируется. Возможны исключения, такие как InterruptedException или ExecutionException, которые необходимо обработать.

💁‍♂️ Затем поток пул завершается вызовом shutdown().
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10👨‍💻32🔥1💯1
⌨️ Метод для глубокого копирования объектов. Это часто используется, когда нужно создать копию объекта, сохраняя его данные, но не связи с другими объектами.

📌 Вот пример метода для глубокого копирования:

import java.io.*;

public class DeepCopyExample {
public static void main(String[] args) {
Person person = new Person("John", 30);
Person deepCopy = deepCopy(person);

System.out.println("Original: " + person.getName() + ", " + person.getAge());
System.out.println("Deep copy: " + deepCopy.getName() + ", " + deepCopy.getAge());
}

public static <T extends Serializable> T deepCopy(T object) {
try {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);
objectOutputStream.writeObject(object);

ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteInputStream);
T copy = (T) objectInputStream.readObject();

return copy;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}

class Person implements Serializable {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}


В этом примере мы создаем класс Person, который реализует интерфейс Serializable, чтобы объекты этого класса можно было сериализовать и десериализовать. Затем мы создаем метод deepCopy, который принимает объект и возвращает его глубокую копию.

Мы используем ByteArrayOutputStream и ObjectOutputStream, чтобы записать объект в байтовый массив, а затем ByteArrayInputStream и ObjectInputStream, чтобы прочитать копию объекта из массива.

В методе main мы создаем объект Person, затем создаем его глубокую копию с помощью метода deepCopy и выводим на экран значения оригинального и скопированного объекта.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍93🔥2👏1💯1👨‍💻1
⌨️ Использования анонимных классов:

Анонимный класс - это класс без имени, который объявляется и создается внутри другого класса или метода. Он удобен, когда требуется определить класс, который будет использоваться только один раз, и нет необходимости создавать отдельный класс.

public class Main {
interface Greeting {
void sayHello();
}

public static void main(String[] args) {
Greeting greeting = new Greeting() { // объявление и создание анонимного класса
@Override
public void sayHello() {
System.out.println("Привет, мир!");
}
};

greeting.sayHello(); // вызов метода sayHello у анонимного класса
}
}


В данном примере мы определили интерфейс Greeting, содержащий метод sayHello(). Затем, в методе main(), мы создали анонимный класс, реализующий интерфейс Greeting и переопределивший метод sayHello(). Затем мы вызываем метод sayHello() у объекта анонимного класса.

📝Таким образом, анонимные классы предоставляют удобный способ создания и использования классов "на лету", что может быть полезно, когда требуется определить классы, которые будут использоваться только в одном месте программы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍84🔥3👏1
⌨️ Работа с коллекциями элементарных типов данных благодаря классам-оболочкам (Wrapper Classes)


import java.util.ArrayList;
import java.util.List;

public class WrapperExample {
public static void main(String[] args) {
// Создание списка оберток для целых чисел
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);

// Использование методов класса-оболочки
int sum = 0;
for (int i = 0; i < numbers.size(); i++) {
sum += numbers.get(i);
}
System.out.println("Сумма чисел: " + sum);
}
}


В этом примере создается список оберток numbers для целых чисел типа Integer. Затем мы добавляем в список несколько элементов и используем метод get() для получения элементов из списка. Значения оберток автоматически анбоксируются в примитивные типы данных int, и мы можем выполнять с ними операции, например, суммирование.
Использование классов-оболочек позволяет работать с коллекциями элементарных типов данных и обеспечивает удобство и безопасность при работе с ними.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥112👍2👏1
⌨️ Обработка исключений с помощью Try-With-Resources.

Try-With-Resources - это новая конструкция языка, введенная в Java 7, которая облегчает работу с ресурсами такими как файлы или сокеты и сокращает количество кода, необходимого для обработки исключений.

Вот пример использования Try-With-Resources для чтения содержимого файла:

try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}


💻В этом примере мы открываем BufferedReader внутри блока try с помощью конструктора FileReader. Затем мы можем безопасно читать файл внутри этого блока без необходимости явно закрывать ресурс.

После завершения блока try автоматически вызывается метод close() объекта reader, который закрывает файл и освобождает связанные с ним ресурсы. Если возникнет исключение в блоке try, его можно будет обработать в блоке catch после завершения работы с ресурсом.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥3👏2🥰1
🤣35😁6🤯4💯3👍1
⌨️ Использование CompletableFuture для асинхронных операций.

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

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExample {
public static void main(String[] args) {
// Создание CompletableFuture объекта
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");

// Добавление операций после выполнения асинхронной задачи
CompletableFuture<String> result = future.thenApplyAsync(str -> str + " World")
.thenApply(str -> str + "!");

try {
// Ожидание результата
String message = result.get();
System.out.println(message);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}


🧑‍💻В данном примере мы создаем CompletableFuture объект future, который возвращает строку "Hello". Затем мы добавляем операции thenApplyAsync и thenApply, которые обрабатывают результат асинхронной задачи и добавляют к нему слова "World" и "!", соответственно.

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

💁‍♂️ Таким образом, использование CompletableFuture позволяет нам эффективно работать с асинхронными задачами и упрощает обработку результатов. Это может быть особенно полезно в многопоточном или параллельном программировании.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9👨‍💻31
⌨️ Использование Stream API для работы с коллекциями данных.

import java.util.Arrays;
import java.util.List;

public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");

// Фильтрация элементов, начинающихся с буквы "a" и преобразование в верхний регистр
fruits.stream()
.filter(fruit -> fruit.startsWith("a"))
.map(String::toUpperCase)
.forEach(System.out::println);
// Выведет "APPLE"
}
}


📝 В этом примере мы использовали Stream API для фильтрации элементов коллекции, начинающихся с буквы "a", и преобразования их в верхний регистр, а затем вывели результат в консоль. Stream API предоставляет мощный и удобный способ работы с коллекциями данных в Java, позволяя выполнять различные операции, такие как фильтрация, отображение, сортировка, агрегация и многое другое.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥4👏21
⌨️ Код для реализации уникального идентификатора (UUID):

import java.util.UUID;

public class UniqueIdGenerator {

public static void main(String[] args) {
// Генерация случайного уникального идентификатора
UUID uuid = UUID.randomUUID();
System.out.println("Уникальный идентификатор: " + uuid);

// Преобразование уникального идентификатора в строку без тире
String uuidString = uuid.toString().replace("-", "");
System.out.println("Уникальный идентификатор без тире: " + uuidString);
}


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

Это полезно, например, при создании уникального идентификатора для записи в базу данных или для генерации уникального имени файла.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111🥰1👏1
⌨️ Использование класса java.time.Duration для рассчета разницы во времени между двумя моментами.

Код для расчета разницы во времени:




import java.time.Duration;
import java.time.LocalDateTime;

public class TimeDifferenceCalculator {
public static void main(String[] args) {
LocalDateTime startTime = LocalDateTime.of(2022, 1, 1, 10, 0, 0);
LocalDateTime endTime = LocalDateTime.of(2022, 1, 1, 12, 30, 0);

Duration duration = Duration.between(startTime, endTime);

long hours = duration.toHours();
long minutes = duration.toMinutes() % 60;
long seconds = duration.getSeconds() % 60;

System.out.println("Time difference: " + hours + " hours, " + minutes + " minutes, " + seconds + " seconds.");
}
}


В этом примере мы создаем два объекта LocalDateTime - startTime и endTime, представляющие начальное и конечное время соответственно. Затем мы используем метод Duration.between() для расчета разницы во времени между startTime и endTime.

Далее, мы используем методы toHours(), toMinutes() и getSeconds() для получения часов, минут и секунд в полученной разнице времени. Наконец, мы выводим результаты на экран.

Эта фишка полезна для рассчета временных интервалов, например, для измерения времени выполнения определенной операции или анализа времени работы программы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝6👍51🔥1🏆1