Java Learning
18.6K subscribers
1.62K photos
1 video
3 files
1K links
№ 5079899194

Обучающий канал по Java

Ссылка для друга - https://t.iss.one/+ZEYYht6-46w5MDM6

По всем вопросам @mascarov_valentin

Реклама на бирже - https://telega.in/c/Java_per_month
Download Telegram
👀 Проверка состояния wait() в цикле

Когда я только начинал писать код для межпоточной коммуникации с использованием методов wait(), notify() и notifyAll(), я использовал if для проверки условия ожидания перед вызовом wait() и notify():

synchronized(queue) {
if(queue.isFull()){
queue.wait();
}
}


🗣️ К счастью, проблем не возникло, но я понял свою ошибку, прочитав раздел из книги Effective Java. Там сказано, что условие ожидания следует проверять в цикле, потому что потоки могут получать ложные уведомления, и до того, как вы что-то сделаете, условие может снова стать истинным. Поэтому правильный способ использования wait() и notify() выглядит так:


synchronized(queue) {
while(queue.isFull()){
queue.wait();
}
}


Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
➡️ Обработка CloneNotSupportedException и возврат экземпляра подкласса

Несмотря на критику функции клонирования объектов в Java, если вам нужно реализовать метод clone(), вот несколько лучших практик для упрощения задачи:

public Course clone() {
Course c = null;
try {
c = (Course)super.clone();
} catch (CloneNotSupportedException e) {} // Не произойдет

return c;
}


🗣️ Этот код использует тот факт, что метод clone() не вызовет CloneNotSupportedException, если класс реализует интерфейс Cloneable. Возврат подкласса называется ковариантным переопределением методов и доступен с Java 5, что позволяет избежать приведения типа на стороне клиента:

Course javaBeginners = new Course("Java", 100, 10);
Course clone = javaBeginners.clone();


Ранее, например, с классом Date, нужно было явно приводить результат метода clone():

Date d = new Date();
Date clone = (Date) d.clone();


Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
➡️ Используйте интерфейсы, когда это возможно

Раньше я использовал конкретные классы, например ArrayList, Vector, и HashMap для возвращаемых значений и аргументов методов.

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

✔️ Лучше использовать интерфейсы. Например, для упорядоченного списка с дубликатами используйте java.util.List, для неупорядоченного набора без дубликатов — java.util.Set, а для контейнера — Collection. Это позволит легко менять реализации.

Можно ещё больше упростить с помощью обобщений и extends. Например, вы можете использовать List<? extends Number>, что позволит передавать List<Integer> или List<Short>.


Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92
➡️ Использование Iterator для перебора List

В Java есть несколько способов перебрать список: цикл for с индексом, расширенный for и Iterator. Раньше я использовал цикл for с методом get(), как показано ниже:

for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
}


🗣️ Этот метод работает для ArrayList, но если список — это LinkedList или другая реализация без поддержки случайного доступа, время выполнения увеличится до O(N^2), потому что get() для LinkedList имеет O(n) сложность.

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


✔️ Лучше использовать Iterator, который является стандартным способом перебора списка:

Iterator<String> itr = list.iterator();

while (itr.hasNext()) {
String name = itr.next();
}


Это безопаснее и предотвращает непредсказуемое поведение.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍161
⚙️ Использование Dependency Injection в коде

Ранее я писал код следующим образом:

public class Game {

private HighScoreService service = HighScoreService.getInstance();

public void showLeaderBoard() {
List listOfTopPlayers = service.getLeaderBoard();
System.out.println(listOfTopPlayers);
}

}


🗣️ Этот подход вызывает несколько проблем:

Класс Game жестко связан с классом HighScoreService, что усложняет тестирование Game в изоляции.

Даже при наличии класса HighScoreService сложно протестировать Game, если HighScoreService делает сетевые запросы или загружает данные с серверов. Мок-объекты здесь не подходят.

✔️ Решение: переписать класс Game с использованием Dependency Injection (DI).

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Что будет выведено при выполнении кода?

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ответ:
Anonymous Quiz
11%
10
80%
15
2%
20
7%
5
👍6
➡️ Закрытие потоков в собственном блоке try

Раньше я закрывал потоки InputStream и OutputStream следующим образом:

InputStream is = null;
OutputStream os = null;

try {
is = new FileInputStream("application.json");
os = new FileOutputStream("application.log");
} catch (IOException io) {
// Обработка исключения
} finally {
is.close();
os.close();
}


🗣️ Проблема в том, что если первый поток вызовет исключение, то закрытие второго потока никогда не произойдет.

✔️ Правильный способ:

InputStream is = null;
OutputStream os = null;

try {

is = new FileInputStream("../input/fxrates.txt");
os = new FileOutputStream("../output/fxrates.txt");

......

} finally {

try { if (is != null) is.close(); } catch(IOException e) {//closing quietly}
try { if (os != null) os.close(); } catch(IOException e) {//closing quietly}

}


Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🤔41😁1
⚙️ Метод forEach()

Java 8 добавила метод forEach() в интерфейс java.lang.Iterable, что упрощает работу с коллекциями и повышает читаемость кода.

✔️ Вместо создания и использования Iterator можно использовать forEach() для обхода элементов.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
➡️ Maven

Maven — один из трёх самых популярных инструментов для сборки проектов на Java. Он отвечает за компиляцию, создание jar-файлов (Java-архивов), создание дистрибутива программы, генерацию документации.

🗣️ Maven — просто отличная штука, хоть поначалу и не очень понятная. Если вы никогда не использовали Maven раньше, вы многое потеряли.

🔗 Ссылочка на доку

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
⚙️ Параллелизм в Java 8

В Java 8 было внесено несколько крупных изменений, улучшивших API параллелизма, включая метод newWorkStealingPool().

🗣️ Этот метод создает пул потоков, использующий алгоритм воровства работы, который может использовать доступные процессоры на желаемом уровне параллелизма.

➡️ Другие улучшения в API параллелизма включают:

Новые методы для ConcurrentHashMap: forEach(), forEachEntry(), forEachValue(), reduce(), merge() и search().
CompletableFuture может явно устанавливать свое значение и статус.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
➡️ Генерация PDF в Java с использованием iText JAR

⚙️ Этот код создает PDF-файл "Test.pdf" в указанном пути и добавляет в него два абзаца: один с текстом "Hello Kiran" и второй с текущей датой.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥31
🌐 Настройка HTTP-прокси в Java

Этот код настраивает HTTP-прокси для Java-приложения, устанавливая адрес, порт, имя пользователя и пароль прокси-сервера.

✔️ Это позволяет направлять запросы через прокси для обхода ограничений или повышения безопасности.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
➡️ Пример Singleton в Java

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


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

Во второй реализации используется перечисление (enum), что обеспечивает автоматическую гарантию единственного экземпляра и потокобезопасность.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
➡️ Скриншот в Java

🗣️ Этот код выполняет захват экрана и сохраняет его как изображение в формате PNG.


Получает размер экрана с помощью Toolkit.getDefaultToolkit().getScreenSize().

Создает прямоугольник, соответствующий размеру экрана.

Создает объект Robot для выполнения действий, связанных с автоматизацией, таких как захват экрана.

Захватывает изображение экрана в виде объекта BufferedImage.

Сохраняет захваченное изображение в файл с указанным именем и форматом PNG с помощью ImageIO.write().

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13😁1
➡️ Отправка email с использованием JavaMail API

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

⚙️ Настраивается соединение с SMTP-сервером, создается сессия и сообщение. Устанавливаются адрес отправителя и получателей, заголовки, тема и текст сообщения.

✔️ Затем сообщение отправляется с помощью метода Transport.send.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
➡️ Создаем PDF-файл в Java

Этот код создает PDF-файл с использованием библиотеки iText в Java.

Внутри метода main создается новый PDF-документ, добавляются два параграфа: один с текстом "Hello Kiran" и второй с текущей датой и временем.

Затем документ сохраняется в файл C:\Test.pdf. Если возникает ошибка, она выводится в консоль.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
⚙️ Преобразование java.util.Date в java.sql.Date

Этот код преобразует дату из формата Java java.util.Date в формат java.sql.Date, который используется для работы с базами данных.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
📁 Удобное чтение и запись файлов в Java

Работа с файлами в Java — одна из самых распространенных задач.

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


➡️ Пояснение к коду:

Использование java.nio.file.Files и java.nio.file.Paths: Эти классы из пакета java.nio предоставляют удобные методы для работы с файлами и путями.

Метод readFileToString: Читает содержимое файла и возвращает его в виде строки. Метод Files.readAllBytes считывает все байты из файла и преобразует их в строку с использованием заданной кодировки.

Метод writeStringToFile: Записывает строку в файл. Метод Files.write записывает байты строки в файл с использованием указанной кодировки.

Обработка исключений: В случае ошибок ввода-вывода, они обрабатываются с помощью блока try-catch, и выводится сообщение об ошибке.
Заключение

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
➡️ Удобное преобразование строк с помощью StringJoiner

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

✔️ В Java 8 был введен класс StringJoiner, который значительно упрощает эту задачу.

Java Learning 👩‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11