13 февраля 2024

☕📦 10 Java-библиотек, которые изменят твой код навсегда

Программирую на Java начиная с JDK 1.6, почти побил мировой рекорд по переписыванию легаси проектов, написал гигабайты кода на Spring Framework. В свободное время обучаю людей программированию и перевожу IT статьи.
Из этой статьи вы узнаете о ключевых возможностях 10 популярных библиотек для Java: работа с коллекциями, строками, JSON, логами, датами и временем и многое другое.
☕📦 10 Java-библиотек, которые изменят твой код навсегда
Данная статья является переводом. Ссылка на оригинал.

1. Guava — библиотеки Google Core для Java

Guava — библиотеки Google Core для Java
Guava — библиотеки Google Core для Java

Guava содержит варианты различных коллекций и набор утилит по работе с ними. Самые примечательные из них – это Immutable-коллекции, в частности, ImmutableList и ImmutableMap. Эти коллекции специально сделаны неизменяемыми.

Guava также поддерживает концепцию функционального программирования в Java, помогающей сделать ваш код проще: утилиты для работы с функциональными интерфейсами Function и Predicate, позволяющие писать код более читабельно и лаконично.

В Guava встроена утилита кэширования CacheBuilder , которая предоставляет простое API для создания и управления кэшем в памяти приложения, вместе с такими настройками, как время действия, атомарная работа и политика очистки.

Примечание

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

Фрагмент кода

Пример кода с использованием Guava для создания неизменяемой коллекции.

GuavaExample 
        import com.google.common.collect.ImmutableList;
 
public class GuavaExample {
    public static void main(String[] args) {
        // Creating an immutable list using Guava
        ImmutableList<String> immutableList = ImmutableList.of("Java", "Guava", "Library");
 
        // Printing the elements of the immutable list
        for (String element : immutableList) {
            System.out.println(element);
        }
    }
}
    

В этом примере ImmutableList.of из Guava используется для создания списка. Список не может быть отредактирован после создания и гарантирует потокобезопасность.

Библиотека джависта
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека джависта»
🎓☕ Библиотека Java для собеса
Подтянуть свои знания по Java вы можете на нашем телеграм-канале «Библиотека Java для собеса»
🧩☕Библиотека задач по Java
Интересные задачи по Java для практики можно найти на нашем телеграм-канале «Библиотека задач по Java»

2. Apache Commons

Библиотека Apache Commons
Библиотека Apache Commons

Библиотека Apache Commons поможет в конфигурировании, работе с файлами, математическими операциями и работе с текстом. Каждый компонент Apache Commons проектировался как самостоятельный модуль, позволяющий разработчикам выбирать, в какой ситуации лучше его использовать.

Например класс StringUtils предоставляет широкий выбор операций со строками. Он содержит такие реализации, как проверка на наличие символов в строке, заглавных букв, null и множество других вариантов операций.

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

Примечание

Несмотря на то что Apache Commons является ценной находкой для Java-программиста, ее обширный функционал можно считать излишним для маленького проекта.

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

Фрагмент кода

Пример кода с использованием Apache Commons для проверки на наличие символов в строке и отсутствие null:

ApacheCommonsExample 
        import org.apache.commons.lang3.StringUtils;
 
public class ApacheCommonsExample {
    public static void main(String[] args) {
        // Checking if a string is empty or null using Apache Commons
        String text = "Hello, Apache Commons!";
         
        if (StringUtils.isNotEmpty(text)) {
            System.out.println("The string is not empty or null.");
        } else {
            System.out.println("The string is either empty or null.");
        }
    }
}
    

В этом примере StringUtils.isNotEmpty из Apache Commons используется для проверки строки на наличие символов или отсутствие null, предоставляя удобный и читабельный путь для обработки таких кейсов.

3. Lombok

Библиотека Lombok
Библиотека Lombok

Lombok является ключевой библиотекой для снижения количества однотипного кода с помощью аннотаций, которые автоматически генерируют простые структуры кода при компиляции проекта. Это упрощает процесс разработки автоматически созданными методами, такими как геттеры, сеттеры, сравнение объектов и приведение к строке. Целью Lombok является повышение читабельности и рефакторинга кода с помощью уменьшения количества повторяющегося и шаблонного кода.

Одна из ключевых фич Lombok — это @Data аннотация, которая комбинирует в себе функциональность нескольких других, таких как @Getter, @Setter, @ToString, @EqualsAndHashCode и @RequiredArgsConstructor. Устанавливая аннотацию @Data над классом, разработчики могут автоматически генерировать геттеры и сеттеры для всех полей, необходимый метод toString и подходящие имплементации для equals и hashCode. Это приводит к более лаконичному и чистому коду, особенно для классов, которые являются моделями данных.

Lombok также включает в себя аннотации @Builder для простой реализации шаблона проектирования Строитель, @Slf4j для тривиальной интеграции с Simple Logging Facade для Java (Slf4j), и @NoArgsConstructor и @AllArgsConstructor для генерации конструкторов без аргументов и со всеми аргументами, соответственно.

Примечание

Несмотря на то как Lombok значительно сокращает шаблонизированный код, разработчики должны понимать принцип генерации кода. Сгенерированные методы не будут такими, как в оригинальном файле с программным кодом, и вследствие этого декомпилированный код будет менее читабельным.

Фрагмент кода

Person 
        import lombok.Data;
 
@Data
public class Person {
    private String name;
    private int age;
}
    

В этом примере аннотация @Data автоматически генерирует геттеры, сеттеры, toString, equals и hashCode методы для класса Person. Этот сжатый и лаконичный код позволяет разработчикам сфокусировать свое внимание на основной логике класса без необходимости в написании шаблонного кода для простых методов.

4. Jackson

Библиотека Jackson
Библиотека Jackson

Jackson — популярная библиотека для быстрого и гибкого преобразования Java-объектов в JSON-формат и обратно.

Преобразование Java объектов в JSON и наоборот происходит с помощью декларативного метода описания аннотациями и программной конфигурацией. Такая аннотация как @JsonProperty позволяет детализированно контролировать весь процесс преобразования и дает возможность разработчикам изменять название полей в JSON-представлении.

Jackson также поддерживает различные форматы данных и умеет работать с полиморфизмом. В этой библиотеке содержатся модули для обработки таких форматов данных как XML, YAML, Protocol Buffers. Также Jackson поддерживает обработки абстрактных классов и интерфейсов, что помогает использовать его в сценариях с ООП-иерархией, где нужно безошибочно преобразовать данные в JSON.

Примечание

Также Jackson предоставляет возможность самостоятельно изменять логику обработки данных. Например, самописные serializer и deserializer. Это очень гибко и удобно, но для этого требуется хорошее понимание основ Jackson.

Фрагмент кода

Пример кода с использованием Jackson-сериализации Java-объекта в JSON-формат данных:

JacksonExample
        import com.fasterxml.jackson.databind.ObjectMapper;
 
public class JacksonExample {
    public static void main(String[] args) throws Exception {
        // Creating a simple Java object
        Person person = new Person("John Doe", 30);
 
        // Serializing the Java object to JSON
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(person);
 
        // Printing the JSON representation
        System.out.println(json);
    }
}
    

В этом примере Jackson использует ObjectMapper для сериализации объекта Person в JSON-строку.

5. Slf4j (Simple Logging Facade for Java)

Библиотека Slf4j
Библиотека Slf4j

Slf4j — это инструмент логирования, который предоставляет реализацию простых фасадов и абстракций для множества фреймворков логирования. Его первостепенная цель — это стандартизация API, с помощью которого разработчики могут использовать простые интерфейсы, одновременно меняя или адаптируя различные реализации логирования в режиме работы приложения. Slf4j не служит как система логирования, а наоборот является мостом между приложением и основным фреймворком логирования.

Главная особенность Slf4j — простота. В нем представлен набор уровней логирования приложения, таких как debug, info, warn и error, тем самым упрощая разработчикам настройку журналирования в их приложении. Используя Slf4j, разработчики должны избегать прямого использования специфичного фреймворка логирования, создавая свое приложение модульным и адаптивным.

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

Примечание

Одним из основных советов для использования Slf4j является реализация актуальной имплементации логгера. Slf4j служит как некий фасад, и разработчикам нужно подобрать совместимый с ним фреймворк для логирования (такой как Logback или Log4j) и подключить его в проект. Такая модульная разработка позволяет достичь гибкости, но не требует для этого дополнительной конфигурации.

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

Фрагмент кода

Пример кода с использованием Slf4j для логирования:

Slf4jExample 
        import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class Slf4jExample {
    // Creating a logger using Slf4j
    private static final Logger logger = LoggerFactory.getLogger(Slf4jExample.class);
 
    public static void main(String[] args) {
        // Logging statements using Slf4j
        logger.debug("Debug message");
        logger.info("Info message");
        logger.warn("Warning message");
        logger.error("Error message");
    }
}
    

В этом примере Slf4j Logger используется для журналирования разных уровней лога. Есть подключенный фреймворк логирования (Logback), который определяет, как эти сообщения будут обрабатываться в режиме реального времени.

6. JUnit

Фреймворк JUnit
Фреймворк JUnit

JUnit самый широко используемый фреймворк для тестирования Java, который предоставляет стандартизированные пути написания и выполнения тестов. Его первостепенной задачей является упрощение процесса юнит тестирования: тестирование отдельных блоков или всего приложения в целом. JUnit следует принципу TDD (test-driven development), который мотивирует разработчиков писать тесты до начала разработки программного кода.

Одна из ключевых особенностей JUnit — это декларативный способ описания тестов с помощью аннотаций. Разработчики используют такие аннотации как @Test, описывая метод, который является частью сценария для тестирования. JUnit также поддерживает такие аннотации, как @Before и @After для выполнения настроек сценария тестирования до запуска или после.

JUnit обладает богатым ассортиментом методов сравнения и валидации ожидаемого результата тестирования. Это нужно для простоты формулировки условий тестирования. Сравнение включает в себя такие методы, как assertEquals, assertTrue, и assertNotNull. Когда сравнение провалено, JUnit выводит сообщение, помогающее разработчику в быстрой диагностике проблемы и ее немедленному исправлению.

JUnit интегрирован с любой средой разработки и различными инструментами, такими как Eclipse, Idea и Maven. Возможность запускать тесты из командной строки или в рамках пайплайна среды непрерывной интеграции улучшают общий процесс работы с тестами.

Примечание

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

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

Фрагмент кода

Пример кода с тестированием арифметических операций при помощи JUnit:

MathOperationsTest 
        import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
 
public class MathOperationsTest {
 
    @Test
    public void testAddition() {
        int result = MathOperations.add(3, 5);
        assertEquals(8, result, "Adding 3 and 5 should equal 8");
    }
}
    

В этом примере аннотация @Test говорит о том, что метод testAddition является тестом. Метод assertEquals проверяет, равно ли 8 результату сложения чисел 5 и 3. JUnit четко дает понять в сообщении о том, что тест провален.

7. Joda-Time

Библиотека Joda-Time
Библиотека Joda-Time

Joda-Time широко используется как популярная библиотека для работы с датой и временем, разработанная с учетом недостатков устаревших классов java.util.Date и java.util.Calendar. Она предоставляет более комплексный и всесторонний подход к проектированию API для обработки операций с датой и временем. Joda-Time известна своей простотой использования, неизменяемостью и поддержкой различных вариантов систем календарей.

Ключевая фича этой библиотеки заключается в том, что класс DateTime содержит не только время, но и временную зону. Этот класс, наряду и с другими LocalDate и LocalTime упрощает основные операции с датой и временем. Joda-Time содержит концепцию неизменяемости, означающую, что однажды созданный DateTime уже не будет потом изменен. Неизменяемость помогает достичь потокобезопасности и избежать непредвиденных ошибок в приложении.

Joda-Time предлагает богатый выбор различных методов для форматирования даты и времени. К этим операциям можно отнести добавление, вычитание и сравнение, которые упрощают разработчикам написание логики в сжатом и понятном виде. Библиотека также содержит утилиты для парсинга и отображение даты в различных форматах.

Другая выдающаяся особенность Joda-Time это поддержка разных календарных систем, включая григорианскую и ISO. Такая гибкость очень нужна, когда вы разрабатываете интернациональные приложения не в формате григорианского календаря.

Примечание

Joda-Time являет впечатляющей библиотекой, но разработчики должны знать о том, что начиная с Java 8 есть такой пакет, как java.time API. Он является частью стандартных библиотек и может быть полезен в решении вашей задачи.

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

Фрагмент кода

Пример кода с использованием Joda-Time для расчета разницы в днях между двумя датами:

DateDifferenceExample 
        import org.joda.time.DateTime;
import org.joda.time.Days;
 
public class DateDifferenceExample {
 
    public static void main(String[] args) {
        // Creating two DateTime objects representing different dates
        DateTime startDate = new DateTime(2022, 1, 1, 0, 0);
        DateTime endDate = new DateTime(2022, 1, 10, 0, 0);
 
        // Calculating the difference in days
        int daysDifference = Days.daysBetween(startDate, endDate).getDays();
 
        // Printing the result
        System.out.println("The difference in days is: " + daysDifference);
    }
}
    

В этом примере классы DateTime и Days используются для расчета разницы в днях между двумя датами. Результат выводится в консоль.

8. Spring Framework

 Spring Framework
Spring Framework

Spring Framework обеспечивает целостный подход к разработке приложений, предлагая решения для различных реализаций, таких как паттерн внедрения зависимостей, аспектно-ориентированное программирование, базы данных, управление транзакциями и т. д. Одна из ключевых целей Spring Framework является простое создание сложных комплексных, масштабированных и расширяемых Java-приложений.

Поддержка паттерна инверсионного контроля (IoC) и паттерна внедрения зависимостей (DI) — ключевые особенности этого фреймворка. IoC берет на себя ответственность за управление зависимостями и жизненным циклом объекта, делегируя это фреймворку. Механизм DI позволяет разработчикам описывать и внедрять классы на основе описанной конфигурации, делающей приложение более гибким и тестируемым.

Spring’s AOP (аспектно-ориентированное программирование) позволяет разработчикам работать со сквозными процессами (spring прокси) такими как логирование, безопасность и управление транзакциями. Он способствует более правильной организации кода и его множественного переиспользования для группировки случайно разбросанного по коду функционала.

Экосистема Spring содержит различные проекты и модули для решения различных задач программирования. Spring MVC обеспечивает надежный инструментарий для создания веб-приложений, а Spring Data упрощает доступ к базе данных с помощью последовательных абстракций. Spring Boot конструирует процесс готовых к использованию приложений с учетом соглашений и значений по умолчанию.

Фреймворк интегрирован с другими технологиями, такими как Hibernate для ORM (Object-Relational Mapping) и поддерживает декларативное управление транзакциями, которое способствует его популярности при разработке приложений.

Примечание

В то время как Spring Framework обеспечивает исчерпывающие возможности для реализации приложений, разработчики должны осознано подбирать модули для решений ключевых задач их приложения. Чрезмерное использование фич и модулей может неоправданно усложнить процесс разработки.

Понимание концепций IoC, DI, и AOP является необходимым для использования Spring Framework. Новые разработчики должны потратить много времени на изучение этих основных принципов, чтобы максимизировать преимущества этого фреймворка.

Фрагмент кода

Пример кода с использованием паттерна внедрения зависимостей Spring:

GreetingService 
        import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class GreetingService {
 
    private final MessageProvider messageProvider;
 
    @Autowired
    public GreetingService(MessageProvider messageProvider) {
        this.messageProvider = messageProvider;
    }
 
    public String greet() {
        return "Hello, " + messageProvider.getMessage();
    }
}
    

В этом примере в класс GreetingService внедряется зависимость MessageProvider . Аннотация @Autowired сообщает контейнеру Spring, что нужно внедрить эту обязательную зависимость для создания экземпляра класса GreetingService. Это помогает создать не связанное между собой приложение.

9. Gson

Библиотека Gson
Библиотека Gson

Gson является популярной Java-библиотекой от Google для сериализации и десериализации объектов Java в JSON-формат. Gson плавно конвертирует Java-объекты в их JSON-представление и наоборот, что делает его ценным инструментом для взаимодействия между приложениями.

Используя минимальное количество кода, разработчики могут с легкостью конвертировать JSON-объекты, используя для этой задачи лишь одну строчку реализации. Gson разрабатывался с фокусированием на легкую интеграцию, и это помогает с легкостью работать с различными сложными иерархиями, коллекциями и типами данных по умолчанию.

Он также поддерживает настроечные аннотации, которые дают возможность разработчикам контролировать процесс преобразования. Такая аннотация, как @SerializedName дает возможность преобразовывать поля со специфичным именем. Эта гибкость очень помогает на практике, в особенности со специфичными JSON-структурами.

Gson предоставляет мощное потоковое API, которое дает возможность разработчикам эффективно реализовывать большие JSON-документы без загрузки в память. Это эффективно в тех приложениях, где очень трепетно относятся к производительности приложения.

Примечание

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

Gson может быть ситуативным выбором для различных реализаций с высокой нагрузкой при преобразовании JSON-данных, поскольку простота использования в этой библиотеке ставится выше, чем скорость обработки данных. В ситуациях, где нужна супер быстрая сериализация и десериализация, возможно, стоит рассмотреть альтернативные библиотеки.

Фрагмент кода

Простой пример кода с использованием Gson для преобразования Java объекта в JSON:

Person 
        import com.google.gson.Gson;
 
public class Person {
    private String name;
    private int age;
 
    // Getter and setter methods...
 
    public static void main(String[] args) {
        // Creating a Person object
        Person person = new Person();
        person.setName("John Doe");
        person.setAge(30);
 
        // Serializing the Person object to JSON
        Gson gson = new Gson();
        String json = gson.toJson(person);
 
        // Printing the JSON representation
        System.out.println(json);
    }
}
    

В этом примере метод toJson используется для преобразования объекта Person в JSON-строку. В результате, JSON-представление может быть отправлено по сети или сохранено в файл.

10. RxJava

Библиотека RxJava
Библиотека RxJava

RxJava является основной библиотекой реактивного программирования в Java которая расширяет принципы ReactiveX (Reactive Extensions) паттерна этого языка программирования. Реактивное программирование сконцентрировано вокруг идеи с асинхронными и событийными потоками данных, представляющими мощную парадигму для обработки скомпонованных асинхронных операций.

Ключевая фича этой библиотеки — реализованная концепция шаблонов проектирования Observables и Observers. Observable — это поток данных, который будет обрабатываться, а Observer является подписчиком и реагирует на события, которые происходят в Observable. Это позволяет разработчикам быстро строить асинхронные операции в декларативной модели.

RxJava обладает богатым набором инструментов, которые позволяют разработчикам преобразовывать, трансформировать, фильтровать и комбинировать потоки данных. Эти инструменты значительно облегчают работу с асинхронными событиями и упрощают решение сложных процессов в приложении. Такие операции, как map, filter и merge являются самыми мощными в арсенале RxJava.

Конкурентность за потоки и параллелизм свойственны для RxJava. Библиотека помогает разработчикам работать с планировщиками для контроля выполнения содержания Observables и управления конкурентности потоков. Это полезно, когда вы имеете дело со сложными приложениями, где множество асинхронных задач нуждаются в координации и управлении.

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

Примечание

RxJava предоставляет мощные абстракции для обработки асинхронных программ, которые можно использовать в процессе обучения работы с концепциями асинхронных программ. Разработчики, которые переходят на RxJava, потратят не так много времени на ознакомление с Observables, Observers и широким набором доступных операций.

Но для простых приложений это перебор. RxJava хорошо подходит для сложных реализаций, где требуется асинхронная обработка данных. Например в UI, сетевых запросах и событийно-ориентированной архитектуре.

Фрагмент кода

Пример кода с использованием RxJava для создания и обработки потоков с числами:

RxJavaExample 
        import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
 
public class RxJavaExample {
 
    public static void main(String[] args) {
        // Creating an Observable emitting integers from 1 to 5
        Observable<Integer> observable = Observable.just(1, 2, 3, 4, 5);
 
        // Creating an Observer to subscribe to the Observable
        Observer<Integer> observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                // Not used in this example
            }
 
            @Override
            public void onNext(Integer value) {
                System.out.println("Received: " + value);
            }
 
            @Override
            public void onError(Throwable e) {
                System.err.println("Error: " + e.getMessage());
            }
 
            @Override
            public void onComplete() {
                System.out.println("Complete");
            }
        };
 
        // Subscribing the Observer to the Observable
        observable.subscribe(observer);
    }
}
    

В этом примере Observable создан с выделенным ему списком чисел от 1 до 5, Observer используется для подписки и реактивной обработки этих значений. Метод subscribe начинает обработку, и методы класса Observer отвечают полученными значениями в логе, ошибками и сигналом о завершении.

Источники

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ