ar
Feedback

لا تقع ضحية للمخادعين! تيليمتريو يكتشف ويُميّز هذه القنوات 👉 إذا كنت تريد رؤية العلامة، اشترك

Java | Фишки и трюки

Java | Фишки и трюки

الذهاب إلى القناة على Telegram

Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg

إظهار المزيد
6 683
المشتركون
+224 ساعات
-197 أيام
-6730 أيام
أرشيف المشاركات
Ещё один канал про код? ❌ НЕТ: “Что такое ООП” ❌ НЕТ: “Топ-5 вопросов на собесе” ❌ НЕТ: “Почему монолит — это плохо” ✅ ДА: «К
Ещё один канал про код? ❌ НЕТ: “Что такое ООП”   ❌ НЕТ: “Топ-5 вопросов на собесе”   ❌ НЕТ: “Почему монолит — это плохо” ✅ ДА: «Как продать бизнесу рефакторинг»   ✅ ДА: «Как не утонуть в легаси»   ✅ ДА: «Как проектировать, а не тушить» Короче, канал для тех, кто уже умеет писать код и теперь пытается выжить в реальных проектах. erid: 2W5zFJa3bn8

☕️Работа с сохранением и загрузкой прогресса игрока в Java: сериализация данных 😎Задача:
🟢Сохранить состояние игрового объекта (например, класс Player) в файл. 🟢Загрузить данные из файла при старте игры. 🟢Обеспечить корректную работу даже при изменениях в структуре класса. 🟢Обработать возможные ошибки ввода-вывода.
😎Способы решения 🔢Стандартная сериализация Java (Serializable)
🟢Класс реализует интерфейс Serializable, и с помощью ObjectOutputStream и ObjectInputStream объекты записываются и читаются из файла.
🔢Использование JSON или XML
🟢Сериализация в человекочитаемый формат с помощью библиотек, например, Gson, Jackson (для JSON) или JAXB (для XML). Это удобно для отладки и совместимости.
🔢Кастомная сериализация
🟢Реализация собственных методов записи и чтения данных, например, через DataOutputStream/DataInputStream, что даёт больше контроля над форматом и размером файла.
😎Пример реализации на Java с использованием стандартной сериализации
import java.io.*;

class Player implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int level;
    int score;

    public Player(String name, int level, int score) {
        this.name = name;
        this.level = level;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Player{name='" + name + "', level=" + level + ", score=" + score + '}';
    }
}

public class SaveLoadGame {
    public static void savePlayer(Player player, String filename) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
            oos.writeObject(player);
            System.out.println("Прогресс сохранён.");
        } catch (IOException e) {
            System.err.println("Ошибка при сохранении: " + e.getMessage());
        }
    }

    public static Player loadPlayer(String filename) {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
            return (Player) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            System.err.println("Ошибка при загрузке: " + e.getMessage());
            return null;
        }
    }

    public static void main(String[] args) {
        Player player = new Player("Игрок1", 5, 1500);
        String saveFile = "player.dat";

        savePlayer(player, saveFile);

        Player loadedPlayer = loadPlayer(saveFile);
        if (loadedPlayer != null) {
            System.out.println("Загруженный игрок: " + loadedPlayer);
        }
    }
}

☕️Интеграция звуковых эффектов и музыки в игру на Java 😎Задача:
🟢При разработке игр на Java требуется работать со звуком и музыкой. 🟢Нужно подключить звуковые звуки (эффекты и музыку) к игровому проекту. 🟢Реализовать звуковой сигнал в нужные моменты (например, выстрел, прыжок, победа). 🟢Обеспечить громкость и возможность паузы/продолжения музыки. 🟢Оптимизировать загрузку и меры для минимизации задержек и нагрузки на систему.
😎Способы решения 🔢Использование стандартного Java Sound API 🔢Библиотека
🟢javax.sound.sampled позволяет работать с аудиофайлами формата WAV, AIFF и др.
🔢Использование различных библиотек
🟢Например, LWJGL OpenAL , TinySound , JOAL — более мощные и гибкие решения для работы со звуком в играх, 3D-звуке, резервных источниках и других возможностях.
🔢Интеграция с игровыми движками
🟢Если используются игровые движки (например, LibGDX), он обычно предоставляет собственный удобный API для работы со звуком.
😎Пример на Java с использованием стандартного Java Sound API

import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;

public class SoundPlayer {

    private Clip clip;

    // Загрузка и подготовка звукового файла
    public void loadSound(String filepath) {
        try {
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(filepath));
            clip = AudioSystem.getClip();
            clip.open(audioInputStream);
        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
            System.err.println("Ошибка загрузки звука: " + e.getMessage());
        }
    }

    // Воспроизведение звука
    public void play() {
        if (clip == null) return;
        if (clip.isRunning()) clip.stop();
        clip.setFramePosition(0);
        clip.start();
    }

    // Остановка звука
    public void stop() {
        if (clip != null && clip.isRunning()) {
            clip.stop();
        }
    }

    // Регулировка громкости (от 0.0 до 1.0)
    public void setVolume(float volume) {
        if (clip == null) return;
        FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
        float dB = (float)(Math.log10(volume) * 20);
        gainControl.setValue(dB);
    }

    public static void main(String[] args) {
        SoundPlayer sound = new SoundPlayer();
        sound.loadSound("jump.wav"); // Замените на путь к вашему звуковому файлу
        sound.setVolume(0.5f);
        sound.play();

        // Для демонстрации задержка перед завершением программы
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        sound.stop();
    }
}

⌨️ Ссылки на методы — это способ упрощенного вызова методов или конструктора, который позволяет передавать их как аргументы в методы или сохранять в переменных. Ссылки на методы появились в Java 8 и являются частью улучшенной поддержки функционального программирования в языке. Есть несколько видов ссылок на методы: 1️⃣ Ссылка на статический метод Используется для вызова статических методов класса. Синтаксис:

ContainingClass::staticMethodName
Пример:

import java.util.function.Function;

public class MethodReferenceExample {
    public static void main(String[] args) {
        Function<String, Integer> converter = Integer::parseInt;
        Integer number = converter.apply("123");
        System.out.println(number); // 123
    }
}
2️⃣ Ссылка на метод экземпляра конкретного объекта Используется для вызова методов экземпляра объекта. Синтаксис:

containingObject::instanceMethodName
Пример:

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

public class MethodReferenceExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        names.forEach(System.out::println);
    }
}
3️⃣ Ссылка на метод экземпляра произвольного объекта определенного типа Синтаксис:

ContainingType::methodName
Пример:

import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        Function<String, Integer> stringLength = String::length;
        Integer length = stringLength.apply("Hello, World!");
        System.out.println(length); // 13
    }
}
Отличие от предыдущего вида в том, что в предыдущем ссылка на метод получается у конкретного объекта, стало быть вызовется метод этого объекта, а в нашем случае при получении ссылки на метод, мы знаем только метод, но объект у которого вызовется этот метод еще не известен, он будет предоставлен при вызове метода. Код выше будет означать "Hello, World!".length() 4️⃣ Ссылка на конструктор Используется для вызова конструктора. Синтаксис:

ClassName::new
Пример:

import java.util.function.Supplier;

public class MethodReferenceExample {
    public static void main(String[] args) {
        Supplier<MethodReferenceExample> exampleSupplier = MethodReferenceExample::new;
        MethodReferenceExample example = exampleSupplier.get();
        System.out.println(example); // MethodReferenceExample@<hashcode>
    }
}
#java #MethodReference

Скачать файл используя Java NIO Пакет Java NIO предлагает возможность передавать байты между двумя каналами без их буферизаци
Скачать файл используя Java NIO Пакет Java NIO предлагает возможность передавать байты между двумя каналами без их буферизации в памяти приложения. Чтобы прочитать файл по нашему URL-адресу, мы создадим новый ReadableByteChannel из потока URL-адреса. Байты, прочитанные из ReadableByteChannel, будут переданы в FileChannel, соответствующий загружаемому файлу. Используем метод transferFrom() из класса ReadableByteChannel для загрузки байтов с заданного URL-адреса в наш FileChannel. Методы transferTo() и transferFrom() более эффективны, чем простое чтение из потока с использованием буфера. В зависимости от операционной системы данные могут быть перенесены непосредственно из кэша файловой системы в наш файл без копирования каких-либо байтов в память приложения. В системах Linux и UNIX эти методы используют метод нулевого копирования, который уменьшает количество переключений контекста между режимом ядра и пользовательским режимом.

⌨️ Полные и сокращённые версии AND и OR && и || называются сокращёнными логическими операторами AND и OR соответственно, или операторами короткой схемы вычислений. В спецификации Java их ещё зовут условными. Значения их операндов могут быть только булева типа. В отличие от двойных, одиночные & и | называются операторами полной схемы вычислений. Значения их операндов могут быть как только булевыми, так и только целочисленными (вместе с оператором ^ они используются в побитовых операциях). В чём разница? В том, что для операторов & и | всегда вычисляются значения обоих операндов, а при работе операторов && и || второй операнд вычисляется только по необходимости. То есть иногда результат выражения однозначно определён уже по первому операнду: ✔️ Если первый операнд && равен false, то второй не вычисляется, так как уже понятно, что результат всего выражения будет false. ✔️ Если первый операнд || равен true, то второй не вычисляется, так как уже понятно, что || вернёт true. && и || используют как операторы булевой логики. Они оперируют значениями только булева типа и применяются только в логических выражениях.

⌨️ Правила переопределения метода Object.hashCode() Общий совет: выбирать поля, которые с большой долью вероятности будут различаться. Для этого необходимо использовать уникальные, лучше всего примитивные поля, например, такие как id, uuid. При этом нужно следовать правилу, если поля задействованы при вычислении hashCode(), то они должны быть задействованы и при выполнении equals(). ➡️ Могут ли у разных объектов быть одинаковые hashCode()? Да, могут. Метод hashCode() не гарантирует уникальность возвращаемого значения. Ситуация, когда у разных объектов одинаковые хэш коды называется коллизией. Вероятность возникновения коллизии зависит от используемого алгоритма генерации хэш кода.

В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн Но где их находить? Как узнавать о них ран
В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн Но где их находить? Как узнавать о них раньше, чем когда все начнут выкладывать фотографии оттуда? Переходите на канал IT-Мероприятия России. В нём каждый день анонсируются мероприятия со всех городов России 📆 в канале размещаются как онлайн, так и оффлайн мероприятия; 👩‍💻 можно найти ивенты по любому стеку: программирование, frontend-backend разработка, кибербезопасность, дата-аналитика, osint, devops и другие; 🎙 разнообразные форматы мероприятий: митапы с коллегами по цеху, конференции и вебинары с известными опытными специалистами, форумы и олимпиады от важных представителей индустрии и многое другое А чтобы не искать по разным форумам и чатам новости о предстоящих ивентах: 🚀 IT-мероприятия России — подписывайся и будь в курсе всех предстоящих мероприятий!

⌨️ instanceof или getClass() == ... Часто нам нужно проверить является ли объект экземпляром определенного класса, например в методе equals(). Существует несколько способов это сделать. Разберём два из них. instanceof проверяет, является ли ссылка на объект в левой части экземпляром типа в правой части или каким-либо подтипом. getClass() == ... проверяет, идентичны ли типы. Выбирать способ проверки типа нужно исходя из решаемой задачи. В методе equals() можно использовать оба способа в зависимости от того собираетесь ли вы позволять сравнивать объект определенного класса и объект класса наследника.

class Parent { }
class Child extends Parent { }

public class Test {
    public static void main(String[] args) {
        Parent parent = new Parent();
        Child child = new Child();
        System.out.println(parent instanceof Parent); // true
        System.out.println(child instanceof Parent); // true
        System.out.println(parent.getClass() == Parent.class); // true
        System.out.println(child.getClass() == Parent.class); // false
    }
}
#java #instanceof #getClass

⌨️ Есть класс Point{int x, y;}. Почему хэш код в виде 31 * x + y предпочтительнее чем x + y? Множитель создает зависимость значения хэш кода от очередности обработки полей, что в итоге порождает лучшую хэш функцию.

⌨️ try-catch-finally try — данное ключевое слово используется для отметки начала блока кода, который потенциально может привести к ошибке. catch — ключевое слово для отметки начала блока кода, предназначенного для перехвата и обработки исключений в случае их возникновения. finally — ключевое слово для отметки начала блока кода, который является дополнительным. Этот блок помещается после последнего блока catch. Управление передаётся в блок finally в любом случае, было выброшено исключение или нет. Общий вид конструкции для обработки исключительной ситуации выглядит следующим образом:

try { 
    //код, который потенциально может привести к исключительной ситуации 
} 
catch(SomeException e ) { //в скобках указывается класс конкретной ожидаемой ошибки  
    //код обработки исключительной ситуации
} 
finally {
    //необязательный блок, код которого выполняется в любом случае
}
Возможно ли использование блока try-finally (без catch)? Такая запись допустима, но смысла в такой записи не так много, всё же лучше иметь блок catch, в котором будет обрабатываться необходимое исключение.

⌨️ Что такое generics? Generics - это технический термин, обозначающий набор свойств языка позволяющих определять и использовать обобщенные типы и методы. Обобщенные типы или методы отличаются от обычных тем, что имеют типизированные параметры. Примером использования обобщенных типов может служить Java Collection Framework. Так, класс LinkedList<E> - типичный обобщенный тип. Он содержит параметр E, который представляет тип элементов, которые будут храниться в коллекции. Создание объектов обобщенных типов происходит посредством замены параметризированных типов реальными типами данных. Вместо того, чтобы просто использовать LinkedList, ничего не говоря о типе элемента в списке, предлагается использовать точное указание типа LinkedList<String>, LinkedList<Integer> и т.п.

⌨️ Иерархия исключений Исключения делятся на несколько классов, но все они имеют общего предка — класс Throwable, потомками которого являются классы Exception и Error. Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память доступная виртуальной машине. Исключения (Exceptions) являются результатом проблем в программе, которые в принципе решаемы, предсказуемы и последствия которых возможно устранить внутри программы. Например, произошло деление целого числа на ноль.

⌨️ В какой последовательности указывать блоки catch? Предположим, есть метод, который может выбросить IOException и FileNotFoundException в какой последовательности должны идти блоки catch? Сколько блоков catch будет выполнено? Общее правило: обрабатывать исключения нужно от «младшего» к старшему. То есть нельзя поставить в первый блок catch(Exception ex) {}, иначе все дальнейшие блоки catch() уже ничего не смогут обработать, так как любое исключение будет соответствовать обработчику catch(Exception ex). Таким образом, исходя из факта, что FileNotFoundException extends IOException сначала нужно обработать FileNotFoundException, а затем уже IOException:

void method() {
    try {
        //...
    } catch (FileNotFoundException ex) {
        //...
    } catch (IOException ex) {
        //...
    }
}
В Java 7 стала доступна новая языковая конструкция, с помощью которой можно перехватывать несколько исключений одним блоком catch:

try {  
    //...
} catch(IOException | SQLException ex) {
    //...
}

Суровый Энтерпрайз - канал действующего java-тимлида одной банковской команды. Канал показывает всю внутреннюю кухню разработ
Суровый Энтерпрайз - канал действующего java-тимлида одной банковской команды. Канал показывает всю внутреннюю кухню разработки в настоящем банковском энтерпрайзе без прикрас. Также множество лайфхаков разработки, построения архитектуры и управления командой. Подписаться

⌨️ В Java static import (статический импорт) позволяет импортировать статические члены (методы и поля) из класса, чтобы использовать их напрямую без указания имени класса. Это может сделать код более читабельным и компактным.

// Для импорта конкретного статического члена
import static package.Clazz.member;

// Для импорта всех статических членов класса
import static package.Clazz.*;
Пример:

public class MathUtils {
    public static final double PI = 3.141592653589793;
    public static int add(int a, int b) {
        return a + b;
    }
    public static int subtract(int a, int b) {
        return a - b;
    }
}

import static MathUtils.PI;
import static MathUtils.add;

public class Main {
    public static void main(String[] args) {
        System.out.println("Value of PI: " + PI);
        System.out.println("Addition result: " + add(5, 3));
    }
}

import static MathUtils.*;

public class Main {
    public static void main(String[] args) {
        System.out.println("Value of PI: " + PI);
        System.out.println("Addition result: " + add(5, 3));
        System.out.println("Subtraction result: " + subtract(5, 3));
    }
}
Плюсы: читаемость, компактность кода. Минусы: - не очевидно откуда берется поле или метод - импорт всех статических членов может привести к конфликтам имен, если разные классы содержат статические члены с одинаковыми именами #java #static #import

1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟 ИТ-событие, которое нельзя пропустить. Участие бесплатное 6 июня разработчики из российских биг
1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟 ИТ-событие, которое нельзя пропустить. Участие бесплатное 6 июня разработчики из российских бигтехов на практических примерах покажут, как ИИ перестал быть экспериментом и стал частью разработки. В программе: — Больше 40 докладов от известных ученых и ИТ-компаний. — Выступления зарубежных спикеров с индексом Хирша более 50. — Концентрация практических кейсов: как создаются большие проекты с применением AI. — Доклады по архитектуре, бэкенд-разработке и построению ИТ-платформ. — AI-интерактивы и технологические квесты. — Пространство для нетворкинга, …а еще after-party со звездным лайн-апом. Когда: 6 июня Где: Москва, МТС Live Холл и онлайн Регистрация по ссылке

⌨️ Stream.reduce() vs Collectors.joining() Когда требуется конкатенировать строки с использованием Stream, можно выбрать один из двух методов: Stream.reduce() или Stream.collect(Collectors.joining()). Пример с Stream.reduce():
List<String> list = List.of("Str1", "Str2", "Str3");
String result = list.stream().reduce("", (a, b) -> a + b);
System.out.println(result); // Str1Str2Str3
Пример с Collectors.joining():
List<String> list = List.of("Str1", "Str2", "Str3");
String result = list.stream().collect(Collectors.joining());
System.out.println(result); // Str1Str2Str3
Использование reduce() для конкатенации строк не является оптимальным с точки зрения производительности. При каждом вызове операции +, создается новая строка, так как строки в Java неизменяемы. Это приводит к увеличению нагрузки на память из-за создания множества промежуточных объектов. В свою очередь, метод Collectors.joining() использует StringBuilder для сборки строк, что значительно эффективнее. Он избегает создания лишних объектов и снижает потребление памяти. #java #Stream #reduce #joining

Есть фича. Есть дедлайн. Есть понимание, что тесты надо писать… но они отъедают время, которого итак впритык. Один наш знаком
Есть фича. Есть дедлайн. Есть понимание, что тесты надо писать… но они отъедают время, которого итак впритык. Один наш знакомый девелопер сказал: «С тех пор как поставил Explyt Test — начал писать меньше тестов… но покрытие стало лучше. Как это вообще возможно?!» Попробуйте сами. Плагин сам предлагает тесты для вашего кода — прямо в IDE. 👉 explyt.ai — сэкономь себе пару часов уже сегодня.