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

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

Відкрити в Telegram

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

Показати більше
6 953
Підписники
-324 години
-27 днів
+630 день
Архів дописів
Подборка каналов IT от наших друзей: 🦥Ленивый программист – подпишись, будем лениться вместе 🎬 Видеоуроки IT  — Самая большая база видеоуроков по IT в Рунете 🐧 Linux Club — Гайды, статьи  и обучающие материалы по Linux. Если хочешь погрузиться в мир Linux, то тебе к нам 📚 Программирование — объёмная библиотека для программистов 🔐 Ленивый безопасник — канал по информационной безопасности с разнообразными техническими материалами на разные темы 🤩 Я хочу стать программистом  — здесь вы найдёте лучшие IT-мемы и прекрасно проведёте время.

☕️GraalVM ускоряет Java с помощью JIT-компиляции и поддерживает мультиязычность и нативную компиляцию. 🔹Пример JIT-ускорения:

public class Demo {
  public static void workload(int a) {
    System.out.println(a + 1); // Простая операция
  }
  public static void main(String[] args) {
    for (int i = 0; i < 100_000; i++) workload(i);
  }
}
🔺Запуск:

java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler Demo
🚀Вызов JavaScript из Java:

import org.graalvm.polyglot.*;
public class Polyglot {
  public static void main(String[] args) {
    try (Context context = Context.create()) {
      int result = context.eval("js", "Math.pow(2, 10)").asInt();
      System.out.println(result); // 1024
    }
  }
}
🔸Нативная компиляция:

native-image -jar app.jar
./app
🔭Работает без JVM! 📈Советы: 1. Для мультиязычности добавьте org.graalvm.sdk. 2. Используйте @CEntryPoint для нативных методов. 3. Тестируйте производительность через jmh. GraalVM позволяет запускать Python и Ruby внутри Java через Polyglot API.

Канал в котором Java-тимлид делиться буднями разработки, без спама, рекламы. Только кровавый Энтерпрайз и обсуждение архитектуры и кода в авторском канале Суровый Энтерпрайз

⌨️ Срезы в стримах. Метод takeWhile В Java 9 появилось два новых метода, полезных для выбора элементов потока с хорошей производительностью: takeWhile и dropWhile. Допустим, у нас есть следующий список блюд:

List<Dish> specialMenu = Arrays.asList(
new Dish("seasonal fruit", 120),
new Dish("prawns", 300),
new Dish("rice", 350),
new Dish("chicken", 400),
new Dish("french fries", 530));
Для получения блюд с калорийностью меньше 320, можно воспользоваться операцией filter. Недостаток операции filter в том, что она требует прохода в цикле по всему потоку данных с применением предиката ко всем элементам. В нашем примере список уже отсортирован по числу калорий. Вместо того, чтобы пройтись по каждому элементу, можно прекратить работу сразу же после обнаружения блюда, содержащего 320 калорий или более. В случае небольшого списка это может показаться не таким уж громадным преимуществом, но при работе с потенциально большим потоком элементов окажется весьма полезным. Поможет нам в этом операция takeWhile! Она позволяет выполнить срез любого потока данных (даже бесконечного) с помощью предиката. И, к счастью, она прекращает работу сразу же по обнаружении неподходящего элемента. Вот как ее следует использовать:

List<Dish> sliceMenu1 
    = specialMenu.stream()
                 .takeWhile(dish -> dish.getCalories() < 320)
                 .collect(toList());
#java #stream #takeWhile

💠Room — это библиотека для работы с локальными базами данных SQLite в Android, предоставляющая удобный интерфейс для взаимодействия с данными. Она является частью Android Jetpack и значительно упрощает управление базами данных, устраняя необходимость писать сложный SQL-код вручную. Room обеспечивает безопасность и упрощает поддержку приложения благодаря проверке запросов на этапе компиляции и автоматической сериализации объектов. ⁉️Почему стоит использовать Room? 1. ✅ Меньше шаблонного кода: Room автоматически обрабатывает многие задачи, такие как создание таблиц, выполнение запросов и преобразование данных. 2. ✅Проверка запросов на этапе компиляции: Если запрос SQL содержит ошибку, она будет обнаружена до запуска приложения. 3. ✅Интеграция с современными инструментами: Room поддерживает работу с LiveData, RxJava, Coroutines и Paging, что делает её идеальной для современных приложений. 4. ✅Удобная миграция данных: Room предоставляет встроенные инструменты для обновления структуры базы данных.Как подключить Room к проекту?
implementation 'androidx.room:room-runtime:2.6.1'
annotationProcessor 'androidx.room:room-compiler:2.6.1'
✔️Для использования Kotlin Coroutines добавьте:
implementation 'androidx.room:room-ktx:2.6.1'
➡️Пример 1: Создание сущности.Сущность представляет таблицу в базе данных. Например:
@Entity(tableName = "users")
public class User {
    @PrimaryKey(autoGenerate = true)
    public int id;

    @ColumnInfo(name = "name")
    public String name;

    @ColumnInfo(name = "age")
    public int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
✔️Аннотация @Entity указывает, что класс является таблицей в базе данных. ➡️Пример 2: Создание DAO. DAO (Data Access Object) определяет методы для взаимодействия с базой данных:
@Dao
public interface UserDao {
    @Insert
    void insert(User user);

    @Query("SELECT * FROM users")
    List getAllUsers();

    @Delete
    void delete(User user);
}
Методы DAO используют аннотации (@Insert, @Query, @Delete) для выполнения операций. ➡️Пример 3: Инициализация базы данных. ✔️Для доступа к базе данных создаётся класс, наследующий RoomDatabase:
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}
✔️Инициализация базы данных:
AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "database-name").build();
UserDao userDao = db.userDao();
➡️Пример 4: Работа с LiveData. ✔️Room легко интегрируется с LiveData для наблюдения за изменениями данных:
// Получение LiveData-списка всех пользователей
@Query("SELECT * FROM users") 
LiveData<List<User>> getAllUsers(); // LiveData<List<User>> - тип возвращаемого значения
✔️В UI можно наблюдать за изменениями данных:
userDao.getAllUsers().observe(this, users -> {
    // Обновление интерфейса при изменении данных
});
➡️Пример 5: Миграция базы данных. ✔️Если структура базы данных изменяется (например, добавляется новое поле), необходимо настроить миграцию:
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE users ADD COLUMN email TEXT");
    }
};
AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "database-name")
    .addMigrations(MIGRATION_1_2)
    .build();
⚡️Советы по использованию Room: 1. Используйте Flow или LiveData для реактивного обновления UI. 2. Оптимизируйте запросы, выбирая только необходимые поля из таблицы. 3. Настройте UPSERT операции, используя стратегию OnConflictStrategy.REPLACE:   
   @Insert(onConflict = OnConflictStrategy.REPLACE)
   void insertOrUpdate(User user);
   
☄️Room — это мощный инструмент для работы с локальными данными в Android-приложениях. Она упрощает взаимодействие с SQLite, делает код более организованным и поддерживаемым, а также интегрируется с современными архитектурными компонентами Android.

😮 Добавлена новая база слитых курсов на 800ГБ: Python: https://t.me/+Bm8ygLluuLllYjBi Программирование: https://t.me/+1VYFsI7EGcZkNjRi Графика и дизайн: https://t.me/+sOPs9gCWP90xMDM6 Frontend и Web: https://t.me/+i_L2xevk0nY2NjBi

☕️Spring WebFlux — реактивный фреймворк для асинхронных веб-приложений в Spring 5. Он работает на серверах Netty, Undertow или Servlet 3.1+ и использует Project Reactor для обработки потоков данных без блокировок. Это позволяет обрабатывать тысячи соединений с минимальным числом потоков, что важно для высоконагруженных систем. 🎯Пример контроллера:
@RestController  
@RequestMapping("/users")  
public class UserController {  
  @GetMapping("/{id}")  
  public Mono getUser(@PathVariable Long id) {  
    return userRepository.findById(id);  
  }  
  @GetMapping("/{id}/orders")  
  public Flux getUserOrders(@PathVariable Long id) {  
    return userRepository.findById(id)  
      .flatMapMany(orderRepository::findByUser);  
  }  
}  
📇WebClient для неблокирующих HTTP-запросов:
WebClient.create("http://service.com")  
  .get()  
  .uri("/data")  
  .retrieve()  
  .bodyToFlux(Data.class)  
  .subscribe(System.out::println);  
📈Советы: 1. Используйте WebFlux для микросервисов с высокой нагрузкой. 2. Комбинируйте с R2DBC для реактивного доступа к БД. 3. Избегайте блокирующих вызовов (JDBC, JPA) в реактивных цепочках. 💠«WebFlux обрабатывает больше запросов с меньшим числом потоков за счет асинхронного планирования».

🔍Тестовое собеседование на Middle Java-разработчика завтра 23 апреля(уже завтра!) в 19:00 по мск приходи онлайн на открытое
🔍Тестовое собеседование на Middle Java-разработчика завтра 23 апреля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика. Как это будет: 📂 Илья Аров, старший разработчик в Т1, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Илья будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Илье Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.  Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqvY2Xdt

☕️Spring Data Envers помогает автоматически отслеживать изменения сущностей в базе данных с помощью Hibernate Envers. 🔺Пример сущности с аудитом:
@Entity  
@Audited  
public class Post {  
  @Id @GeneratedValue  
  private Long id;  
  private String title;  
  private String slug;  
}  
🔺Репозиторий с поддержкой ревизий:
public interface PostRepository extends JpaRepository, RevisionRepository { }  
💠Доступны методы findRevisions() и findLastChangeRevision() для получения истории изменений. 🔻Envers создает таблицы _AUD и REVINFO для хранения версий и метаданных. При изменениях данные копируются в _AUD с типом операции (INSERT, UPDATE, DELETE).
Пример использования:
for (Revision rev : postRepository.findRevisions(postId)) {  
  System.out.println("Версия " + rev.getRevisionNumber() + ": " + rev.getEntity());  
}  
📈Советы: 1. Добавьте зависимости hibernate-envers и spring-data-envers. 2. Включите @EnableJpaAuditing в конфигурации. 3. Для расширенного аудита используйте @CreatedBy и @LastModifiedBy. 🔸Метод findRevisions() возвращает все версии сущности — от создания до удаления.

Проверьте уровень знаний по Kafka — 10 вопросов и честная оценка. 🤔Понимаете ли, как работают консьюмеры, продюсеры и партиц
Проверьте уровень знаний по Kafka — 10 вопросов и честная оценка. 🤔Понимаете ли, как работают консьюмеры, продюсеры и партиции? Или только кажется?  Пройдите короткий тест, чтобы честно оценить свои знания по Kafka. 10 вопросов — и сразу рекомендации, что подтянуть для карьерного роста. 👉🏻Пройти тест👈🏻

☕️GraphQL в Java позволяет клиентам запрашивать только нужные данные, избегая избыточности REST. Пример на Spring Boot: 🔹Схема (schema.graphqls):
type Vehicle {
  id: ID!
  type: String!
  modelCode: String!
}

type Query {
  vehicles: [Vehicle!]!
}
🔻Контроллер:
@Controller
public class VehicleController {
  @QueryMapping
  public List vehicles() {
    return List.of(new Vehicle("1", "bus", "XYZ123"));
  }
}
💠Пример запроса:
{
  vehicles {
    id
    type
  }
}
🔸Ответ:
{
  "data": {
    "vehicles": [{ "id": "1", "type": "bus" }]
  }
}
🔺Для интеграции с БД используйте Spring Data JPA и Querydsl:
public interface VehicleRepo extends JpaRepository, QuerydslPredicateExecutor {}
🔹Maven зависимости:

  org.springframework.boot
  spring-boot-starter-graphql


  com.querydsl
  querydsl-jpa
📈Советы: 1. Включите GraphiQL для интерактивных запросов. 2. Используйте @MutationMapping для мутаций. 3. Настройте кеширование через CacheControl. 🔺GraphQL позволяет запрашивать только нужные поля, снижая нагрузку на сеть.

☕️Checked vs Unchecked исключения 🔹Исключения делятся на проверяемые (checked) и непроверяемые (unchecked). 🔹Checked исключения требуют обязательной обработки или объявления через throws. Обычно связаны с внешними ресурсами: файлами, сетью. 🔎Пример:

public void readConfigFile() {
    try (FileInputStream file = new FileInputStream("config.txt")) {
        int data = file.read();
        System.out.println("Данные: " + data);
    } catch (FileNotFoundException e) {
        System.err.println("Файл не найден!");
    } catch (IOException e) {
        System.err.println("Ошибка ввода-вывода: " + e.getMessage());
    }
}
🔹Unchecked исключения — наследники RuntimeException. Не требуют обработки, сигнализируют о логических ошибках. 🔻 Пример:

public void printLength(String text) {
    if (text == null) throw new IllegalArgumentException("Строка не может быть null!");
    System.out.println("Длина: " + text.length());
}

public int divide(int a, int b) {
    if (b == 0) throw new ArithmeticException("Деление на ноль!");
    return a / b;
}
📈Советы: 1. Для checked используйте try или try-with-resources. 2. Для unchecked проверяйте входные данные. 3. Документируйте исключения через @throws. 🔺Checked — для внешних ошибок, Unchecked — для внутренних багов.

⌨️ Суть лямбда-выражений Лямбда-выражения на первый взгляд могут показаться чем-то сложным и загадочным, но на самом деле они просты и интуитивно понятны. Лямбда-выражение — это лаконичный способ описания анонимной функции, которую можно передать в качестве параметра или сохранить в переменной для последующего использования. Если говорить ещё проще, лямбда-выражение — это просто другой способ создания и реализации объекта определённого типа. Рассмотрим это на примере создания нового потока. У класса Thread есть конструктор:

public Thread(Runnable target) {
    ...
}
То есть в конструктор нужно передать объект типа Runnable. До лямбда-выражений мы сделали бы так:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello World");
    }
}).start();
Здесь мы создаём анонимный класс, реализующий интерфейс Runnable, с определённым методом run. Если использовать лямбда-выражение, тот же код будет выглядеть следующим образом:

Runnable r = () -> System.out.println("Hello World");
new Thread(r).start();
Или проще:

new Thread(() -> System.out.println("Hello World")).start();
Лямбда-выражение заменяет собой анонимный класс, который раньше был бы необходим для реализации Runnable. Лямбда-выражение может использоваться только там, где ожидается реализация функционального интерфейса — интерфейса с единственным абстрактным методом. А интерфейс Runnable именно такой:

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
Функциональный интерфейс должен содержать только один абстрактный метод, чтобы компилятор мог точно определить, какой метод реализует лямбда-выражение. В противном случае возникли бы неоднозначности и ошибки. #java #lambda #Runnable

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

private static final ThreadLocal<DateFormat> dateFormat = 
    ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

void formatDate(Date date) {
    System.out.println(dateFormat.get().format(date)); // У каждого потока свой экземпляр
}
💠Преимущества:  ▸ Избегает создания нового объекта для каждого вызова  ▸ Гарантирует потокобезопасность без блокировок  💠2. Контекст безопасности в веб-приложениях 

public class SecurityContext {
    private static final ThreadLocal<User> currentUser = new ThreadLocal<>();

    public static void login(User user) {
        currentUser.set(user);
    }

    public static User getCurrentUser() {
        return currentUser.get();
    }

    public static void logout() {
        currentUser.remove();
    }
}

// В фильтре сервлета
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
    SecurityContext.login((User) req.getAttribute("user"));
    try {
        chain.doFilter(req, res);
    } finally {
        SecurityContext.logout();
    }
}
💠3. Локальный кэш для тяжелых вычислений 

private static final ThreadLocal<Map<String, String>> cache = 
    ThreadLocal.withInitial(HashMap::new);

void processData(String key) {
    if (!cache.get().containsKey(key)) {
        cache.get().put(key, expensiveOperation(key));
    }
    System.out.println(cache.get().get(key));
}
⚠️ Опасности:  ▸ Утечки памяти в пулах потоков (например, Tomcat)  ▸ Неожиданное поведение при повторном использовании потоков  ▸ Сложность отладки из-за неявной передачи данных  💠Практические кейсы:  ▸ Контекст пользователя в веб-приложениях  ▸ Локальный кэш для тяжелых вычислений  ▸ Параметры локали и форматирования дат

💻Лучшие каналы по ИБ и Хакингу! Hacking & InfoSec Base — канал действующего белого хакера. Подробные уроки по безопасности,
💻Лучшие каналы по ИБ и Хакингу! Hacking & InfoSec Base — канал действующего белого хакера. Подробные уроки по безопасности, эксплуатации уязвимостей, социальной инженерии. CyberGuard — полезные утилиты, софт и литература по информационной безопасности и Хакингу. linux administration — всё, что необходимо знать о Linux и его дистрибутивах. 🫵Подписывайся, здесь ты узнаешь всё о ИБ и Хакинге!

💎Unicode-хаки и комментарии-невидимки в Java  Java поддерживает Unicode во всех частях кода, включая комментарии и имена переменных. Это открывает неочевидные возможности для экспериментов, но требует осторожности в production-коде. 💠1. Исполняемые комментарии через Unicode 

// \u000d System.out.println("Этот код выполнится!");
После компиляции символ \u000d превращается в перенос строки, и код становится: 

// 
System.out.println("Этот код выполнится!");
Применение:  ▸ Демонстрация скрытых уязвимостей в презентациях  ▸ Образовательные эксперименты с компиляцией  ▸ Технические розыгрыши (только для небоевых проектов!)  💠2. Кириллические идентификаторы 

int размер = 10; // переменная "размер"
System.out.println(размер); // 10
💠Плюсы:  ▸ Локализация кода для образовательных проектов  ▸ Поддержка специфических терминов на национальных языках  💠3. Графика через Unicode-символы 

System.out.println("\u2591\u2592\u2593"); // Вывод символов псевдографики: ░ ▒ ▓ (разные уровни заливки)
System.out.println("\u265A \u265B");     // Вывод юникод-символов: ♚ ♛ (шахматные фигуры короля и королевы)
💠Практическое применение:  ▸ Консольные интерфейсы с псевдографикой  ▸ Визуализация данных в текстовом режиме  ▸ Генерация ASCII-арта  💠4. Экранирование спецсимволов 

String regex = "\\p{So}"; // Шаблон для эмодзи и символов
String text = "Alert! ⚠️";
System.out.println(text.replaceAll(regex, "[символ]")); // Alert! [символ]
⚠️ Важные предупреждения:  ▸ Код с Unicode-трюками не проходит код-ревью в серьезных проектах  ▸ Может вызывать проблемы с линтерами и статическими анализаторами  ▸ Затрудняет поиск в кодовой базе (например, \u000d)  💠Альтернативы для безопасного использования: 

// Локализация через ResourceBundle
ResourceBundle bundle = ResourceBundle.getBundle("Messages_ru");  // Загрузка ресурсов для локали ru
String message = bundle.getString("welcome");                    // Получение локализованной строки по ключу

Fresh IT — не про абстрактное лидерство, а про то, как реально вырасти из разработчика в сильного техлида. Александр — техлид
Fresh IT — не про абстрактное лидерство, а про то, как реально вырасти из разработчика в сильного техлида. Александр — техлид, который прошёл весь путь: от фрилансера на jQuery до руководителя разработки в топовых компаниях. И теперь делится тем, о чём молчат курсы: как строить команду, держать качество, договариваться с бизнесом — и не сгореть на этом всём. 📌 В постах найдешь: техники для тех, кто хочет не просто кодить, а управлять;ситуации из жизни тимлида и как из них выходить;мышление, подходы: всё по делу, с примерами и без воды;свежие новости и тренды в IT, которые помогут оставаться востребованным специалистом. Хватит учиться на своих ошибках, когда можно учиться на чужих. Fresh IT — твой быстрый путь от кода к команде. Подписывайся! 🚀

⌨️ Дайте определение понятию «интерфейс». Какие модификаторы по умолчанию имеют поля и методы интерфейсов? Ключевое слово interface используется для создания полностью абстрактных классов. Основное предназначение интерфейса - определять каким образом мы можем использовать класс, который его реализует. Создатель интерфейса определяет имена методов, списки аргументов и типы возвращаемых значений, но не реализует их поведение. Все методы неявно объявляются как public. Начиная с Java 8 в интерфейсах разрешается размещать реализацию методов по умолчанию default и статических static методов. Интерфейс также может содержать и поля. В этом случае они автоматически являются публичными public, статическими static и неизменяемыми final.

⌨️ java.time API (Современные Дата и Время) Старый API даты/времени был неудобным и изменяемым (mutable). Новый пакет java.time (LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Duration, Period) решает эти проблемы!

import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoUnit;

LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(2024, Month.DECEMBER, 31);
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); // Неизменяемый! Возвращает новый объект

System.out.println("Сегодня: " + today);
System.out.println("День рождения: " + birthday);
System.out.println("Через неделю: " + nextWeek);
// Вывод:
// Сегодня: 2023-10-27 (пример)
// День рождения: 2024-12-31
// Через неделю: 2023-11-03 (пример)
Используйте современный, потокобезопасный и интуитивно понятный API! ✨ #java #datetime #java8 #javatime #api #bestpractice

⌨️ Generics (Безопасность типов) Использование "сырых" типов коллекций (вроде List вместо List<String>) опасно! Generics (<>) обеспечивают безопасность типов на этапе компиляции.

// Опасно - можно добавить что угодно, ошибка будет при извлечении
List unsafeList = new ArrayList();
unsafeList.add("Привет");
unsafeList.add(123); // Компилятор не ругается!

// String s = (String) unsafeList.get(1); // ClassCastException во время выполнения!

// Безопасно - только строки!
List<String> safeList = new ArrayList<>();
safeList.add("Привет");
// safeList.add(123); // Ошибка компиляции! Нельзя добавить int в List<String>

String s = safeList.get(0); // Никакого приведения типов не нужно!
#java #generics #typesafety #bestpractice