Język Java rozwija się ostatnio bardzo dynamicznie i z każdą nową wersją daje coraz więcej interesujących możliwości. Jednak nie wszystkie przydatne dla programistów funkcje mogą znaleźć się w bibliotece standardowej języka. Dlatego bardzo często wielu programistów używa zewnętrznych bibliotek. Głównym ich zadaniem jest skrócenie czasu tworzenia pisania kodu i uproszczenie go. Przedstawię Ci dzisiaj, 5 niezbędnych bibliotek języka Java, które ułatwią życie każdemu programiście.
Apache Commons
Jest to jedna z najbardziej znanych bibliotek Javy. Właściwie to grupa bibliotek, które w wielu przypadkach ułatwiają życie. Obecnie to ponad 40 komponentów, które składają się na tę bibliotekę (każdego można używać osobno). A najpopularniejsze z nich to commons-lang, commons-io, commons-cli, commons-text itd. (cała lista tutaj) Warto odwiedzić strony poszczególnych komponentów i zapoznać się z listą klas i metod, jakie są w nich umieszczone. Jedna z najpopularniejszych klas zawartych w commons-lang jest klasa StringUtils, która zawiera bardzo wiele przydatnych metod np. isEmpty(...)
, isBlank(...)
czy revers(...)
.
Mógłbym jeszcze wiele pisać na temat zawartości tej biblioteki, ale jest w niej tyle ciekawych rzeczy, że ciężko jest się skupić na czymś konkretnym. Dodam jeszcze, że nie widziałem poważnego projektu, który by nie korzystał z tej biblioteki. Jako potwierdzenie popularności Apache Commons niech posłużą statystyki zaczerpnięte z mvnrepository.com gdzie możemy zobaczyć, że commons-lang został użyty w ponad 11 tys. artefaktów, a commons-io w ponad 14 tyś.
Guava
Następną bardzo popularną biblioteką, którą mogę zaliczyć do 5 niezbędnych bibliotek języka Java jest Guawa – biblioteka stworzona i przez wiele lat rozwijana przez Google. Guava wprowadzała do Javy wiele idiomów funkcyjnych na długo przed powstaniem Javy 8. Była więc bardzo popularną biblioteką w starszych wersjach 1.6 i 1.7. Mimo tego, że wiele z jej funkcji zostało zastąpionych przez natywne funkcje wbudowane w język, ciągle jest warta uwagi. Można w niej znaleźć wiele ciekawych i przydatnych rozwiązań m.in.:
Niemutowalne kolekcje (Immutable collections)
Do czego w ogóle potrzebne są nam niemutowalne kolekcje? W większości przypadków doskonale sprawdzają się kolekcje z biblioteki standardowej. Jednak w niektórych przypadkach warto skorzystać z czegoś innego.
Niemutowalne kolekcje są to takie kolekcje, do których nie możemy dodawać nowych elementów i też usuwać starych. Jeśli raz utworzymy taką kolekcję, to nie możemy już jej zmienić. Przydaje się to w kilku scenariuszach:
- jeśli używamy kolekcji w kontekście wielowątkowości, to kolekcje niezmienne są bezpieczne wielowątkowo (ThreadSafe) właśnie z tego względu, że po utworzeniu nie można zmienić ich zawartości;
- gdy korzystasz z bibliotek, które nie do końca są zaufane (nie masz pewności czy dana biblioteka nie zmieni twojej kolekcji), warto wtedy jako parametry do metod z danej biblioteki przekazywać w parametrach kolekcje niezmienne;
- kolekcje te są wydajniejsze, ponieważ nie posiadają mechanizmów dodawania i usuwania, więc są bardziej zoptymalizowane pod kątem odczytu.
A utworzyć taką kolekcję można w bardzo łatwy sposób:
ImmutableList<String> list = ImmutableList.of("a","b", "c"); ImmutableSet<String> set = ImmutableSet.of("a","b", "c");
Specjalne rodzaje kolekcji
Poza niemutowalnymi kolekcjami Guava udostępnia nam kilka bardzo ciekawych implementacji kolekcji, których nie znajdziecie w api Javy.
Są to Multiset
, SortedMultiset
, Multimap
, ListMultimap
, SetMultimap
, BiMap
, ClassToInstanceMap
,Table
Multiset
Jest to taki set, który zlicza wystąpienia elementów. Jeśli dodacie kilka razy tą samą wartość do tego seta, to możecie sprawdzić ile było wystąpień danej wartości korzystając z metody count(E)
Multimap
Multimapa jest konstrukcją trochę inną niż multiset. Jeśli dodamy do takiej mapy pod tym samym kluczem kilka wartości, to te wartości zostaną dopisane do listy wartości z danego klucza. W skrócie multimapa jest mapą list Map<T, Collection<V>>, ale pozwala się trochę wygodniej obchodzić z tą konstrukcją, gdyż zachowuje się tak jak gdyby to byłA zwykła mapa Map<K, V>.
BiMap
BiMapa to mapa, która może jest symetryczna, możemy ją traktować jak BiMap<K, V>, ale dzięki metodzie inverse()
możemy ją traktować jak BiMap<V, K>.
Cache
W Guavie jest też prosty mechanizm cache, który jest całkiem dobry do podstawowych zastosowań i nie jest skomplikowany w konfiguracji, dzięki czemu oszczędza trochę czasu w porównaniu do innych rozwiązań.
Jest nawet szyna zdarzeń (EventBus)
Mamy też dostępną szynę zdarzeń, która może być przydatna w małych, a nawet średnich aplikacjach. W sytuacji, gdy potrzebujesz wymieniać informacje między komponentami, taka szyna jest bardzo wygodnym rozwiązaniem. Sprawia, że moduły są ze sobą luźno powiązane, co ułatwia pracę z nimi.
I cała masa klas użytkowych (utils)
Nie ma sensu wyliczać wszystkich dostępnych klas utilowych, bo jest ich całkiem sporo, ale wymienię najważniejsze z nich: Reflection, I/O, Math, Hashing, Primitives itd.
JUnit
Kolejną z 5 niezbędnych bibliotek języka Java jest moim zdaniem JUnit – biblioteka do wykonywania i pisania testów jednostkowych. Trudno wyobrazić sobie profesjonalny projekt bez testów jednostkowych, a Junit to najpopularniejsza biblioteka do testów w świecie Javy.
Krótki przykład testu:
public class SomeClassTest { private SomeClass testedClass; @Test public void testSimplMethod() { boolean result = testedClass.simpleMethod(); assertTrue(result); } }
Mockito
To także biblioteka, bez której ciężko jest prowadzić profesjonalny projekt w Javie. Biblioteka ta służy do mockowania (zaślepiania), zależności w testach jednostkowych. Jest bardzo prosta w użyciu. Przy użyciu kilku adnotacji możemy wstawić zaślepki dla wybranej metody i łatwo ją przetestować w izolacji.
public class SomeClass { @Inject private UserService userService; public boolean simpleMethod() { if (userService.getLoggedUser() != null) { return true; } return false; } } @RunWith(MockitoJUnitRunner.class) public class SomeClassTest { @Mock UserService userService; @InjectMocks private ArticleManager manager; @Test public void shouldReturnTrueWhenUserExists() { when(userService.getLoggedUser()).thenReturn(new User()); boolean result = testedClass.simpleMethod(); assertTrue(result); } @Test public void shouldReturFalseIfUserDoesNotExists() { when(userService.getLoggedUser()).thenReturn(null); boolean result = testedClass.simpleMethod(); assertFalse(result); } }
Log4j
To biblioteka, daje nam możliwość logowania zdarzeń z naszej aplikacji. Biblioteka ta, jak podobne rozwiązania tego typu obsługuje wiele poziomów logowania: trace, debug, info, warn, error, fatal.
Obsługuje różne appender’y, które pozwalają tak skonfigurować log4j by mógł zapisywać logi w różnych miejscach, zwykle jest to plik lub konsola, ale także może być to sql’owa baza danych lub jakieś inne rozwiązanie, np. baza nosql Cassandra, czy MongoDb, a nawet można go skonfigurować tak, by wysyłał logi poprze zapytania http.
Użycie jest bardzo proste, sprowadza się do dwóch linijek:
private static Logger log = Logger.getLogger(LogClass.class); //pobranie instancji logera dla naszej klasy ... log.info("Info Message!"); // logowanie wiadomości
Podsumowanie
Jest wiele przydatnych bibliotek, ja wymieniłem tylko te 5 niezbędnych bibliotek języka Java, które moim zdaniem są niezastąpione w codziennym życiu programisty. Zawsze zanim zaczniesz pracę nad jakimś komponentem upewnij się najpierw, czy już wcześniej ktoś nie napisał czegoś podobnego. Biblioteki są po to, by nam pomagać i nie powielać już raz wykonanej pracy przez kogoś innego. Wiele firm przez lata wypracowuje własne biblioteki, które pomagają rozwiązywać codzienne problemy.
Z drugiej strony pamiętaj, by nie przesadzić z ilością bibliotek, czasem dołączanie do projektu biblioteki tylko po to, by użyć jednej metody jest przerostem formy nad treścią.
Źródła: