Techniki Zaawansowane
8 godz. 35 min · Java · Full-stack i Programowanie
Rafał SolarskiW poczatkowych lekcjach przyjrzymy sie pokladowi, na jakim bedziemy uruchamiali nasze programy. Wykorzystamy VisualVM do podgladania parametrów JVM. Zobaczymy równiez jakie zasoby sa tam dostepne oraz dowiesz sie jak monitorowac to, czy dobrze z nich korzystamy. Opowiemy Ci tez miedzy innymi o tym, jak zrobic heap i thread dump, oraz jak wlaczyc logi GC.
Kolejne lekcje kursu zostaly poswiecone wyrazeniom regularnym. Wyrazenia regularne mozemy wykorzystac nie tylko do walidacji danych wprowadzania przez uzytkownika, ale równiez do dzielenia tekstu oraz wyluskiwania wystapien wzorców w duzym tekscie. W tym rozdziale dowiemy sie miedzy innymi tego, jak mozemy wykorzystac ten potencjal z poziomu Javy.
Dzieki typom generycznym jestesmy w stanie osiagnac bezpieczenstwo typów w trakcie kompilacji przy zachowaniu elastycznosci pisanego kodu. W nastepnym rozdziale kursu przyjrzymy sie temu, jak mozemy je wykorzystac, oraz w jaki sposób czasami nalezy z tego bezpieczenstwa zrezygnowac.
Interfejsy funkcyjne to sposób na przeniesienie odrobiny swiata programowania funkcyjnego do Javy. Gdy polaczymy je z wyrazeniami lambda oraz API strumieni pozwola nam pisac te sama logike w duzo bardziej przejrzysty sposób.
Kolekcje, czyli listy, mapy, zbiory i kolejki to jedne z najczesciej wykorzystywanych klas w codziennej pracy. To jak dobrze poznamy ich mozliwosci ma ogromny wplyw na to, w jaki sposób bedziemy podchodzili do rozwiazywania wyzwan na naszej drodze.
System plików to zasób bez którego ciezko sobie poradzic. Pozwalaja nam na dostarczanie konfiguracji, danych wejsciowych i wyjsciowych, a przez to równiez integrowanie ze soba calych systemów.W tym rozdziale nauczymy sie korzystac z tych dobrodziejstw w bezpieczny sposób wykorzystujac m.in. IO Streams.
Trzymanie daty w String to niekoniecznie najwygodniejszy sposób. Juz od pewnego czasu Java dysponuje bardzo wygodnym Date&Time API - zobaczymy, co mozemy w nim znalezc.
Wielowatkowosc nie jest prosta... i dlugo tak jeszcze pozostanie. Nawet jesli korzystamy z frameworków, które próbuja ja przed nami ukryc, to ciagle musimy byc swiadomi problemów jakie sie z nia wiaza. W tym rozdziale poznamy glówne problemy na jakie mozna natrafic programujac wielowatkowo w Javie. Poznamy równiez klasy, które zdecydowanie pomoga nam zapanowac nad ta zlozonoscia.
JDBC to najbardziej podstawowy sposób laczenia sie z baza SQL z poziomu Javy. W wielu systemach/aplikacjach stosuje sie rozwiazania ORM takie jak JPA/Hibernate. Mimo wszystko warto wiedziec jak to pod spodem dziala oraz umiec poradzic sobie w aplikacjach, gdzie wybrano bardziej "lekkie" podejscie niz Hibernate.
Na koniec kursu wykorzystamy zdobyta wiedze, aby stworzyc prosta aplikacje pozwalajaca na przechowywanie danych o wydatkach. Po stworzeniu coreu aplikacji, mozesz spróbowac uzupelnic go za pomoca GUI.
Ten kurs stworzony zostal przede wszystkim z mysla o osobach, które juz poznaly podstawy jezyka, takie jak zmienne, mechanizmy kontroli wykonania, klasy, typy generyczne.Jezeli chcesz poczuc sie swobodnie nie tylko jesli chodzi o mechanizmy jezyka, ale równiez pod wzgledem znajomosci standardowej biblioteki Javy - to kurs w sam raz dla Ciebie. Materialy beda przydatne dla studentów, którzy znaja juz podstawowa skladnie Javy; programistów Javy chcacych poszerzyc lub uporzadkowac swoja wiedze; programistów innych jezyków, którzy chca poznac inny stack technologiczny.
Cześć w tej lekcji przedstawię ci kilka takich dobrych praktyk związanych
z pracą na strumieniach i na lambdach przejdźmy do kodu takim backgroundem
w pierwszej części lekcji będzie zliczanie duplikatów które są większe od
zera tak tutaj mamy jakiegoś array'a start później są jakieś
integery oraz tutaj autor programu sobie tworzy na początek z tego stream'a
odfiltrowuje elementy które są równe
bądź mniejsze od zera tak czyli zostają tylko te większe od zera no
i liczy ile jest tych elementów później pomysł polega na tym że liczy
to samo tylko teraz robi distinct pomiędzy czyli każdy duplikat
zostanie zmniejszona jego liczebność do jednego tak
czyli tak jak byśmy zrobili sobie zbiór z tego po prostu i później zrobię na tym count
i później można odjąć od siebie te dwie liczby oraz będziemy mieli wtedy właśnie
liczbę duplikatów które spełniają ten predykat ten
kodzik można by go napisać trochę lepiej teraz przyjrzymy
się co tu by można było poprawić po pierwsze ten predykat tutaj on się powtarza
tak to jest jedna rzecz druga rzecz to jest to że kilka
razy tworzymy ten stream tak i on wygląda tak samo od któregoś
momentu zauważ że można by było pomyśleć
o tym żeby wyekstraktować na przykład ten kawałek do jakiejś zmiennej nawet
intellij podpowiada że można ten kawałek stąd też wziąć ale to
nie wyjdzie z tego względu że stream za pierwszym razem został tutaj
używając tego count został sfinalizowany i drugi raz już nie możemy
korzystać z tego samego streamu tutaj dostaliśmy taki ładny wyjątek stream has already
been operated upon or closed prawda okej więc
to nie przejdzie więc możemy raczej pomyśleć trochę inaczej żeby
oczywiście wyciągnąć sobie ten element tutaj ale wcześniej go po
prostu stworzyć z niego jakąś już listę tak nie
strumień no i tutaj możemy po prostu zrobić korektę
i wyciągnąć sobie te listy tak to jest jeden z pomysłów drugą rzeczą którą
tutaj widzimy jest to że są trochę mieszane tak jakby zagadnienia ze względu
na to że to jest mała metodka to tutaj powiedzmy tym się nie przejmujemy tak bardzo ale
gdybyśmy chcieli reużywać trochę tego kodu to można by było w ekstrahować
odfiltrowanie elementów z kolekcji tak
i to na to przyjąć jakąś metodę na przykład filter only positive
i jeszcze drugim zagadnieniem jest dopiero liczenie duplikatów
w kolekcji która już spełnia jakiś predykat tak która została na przykład
odpowiednio wyfiltrowana no i to możemy sobie rozbić na metody ja tutaj trochę teraz przewinę
ponieważ już to zrobiłem i zaraz omówimy jak to wygląda no okej po takim
małym refaktorze to mogłoby wyglądać mniej więcej tak tutaj rozbiłem sobie to na metodach
jak mówiłem mam tutaj metodę która zajmuje się liczeniem duplikatów
oraz mam drugą metodę która odpowiada za filtrowanie tylko pozytywnych
integerów i ok flow wygląda tak najpierw odfiltrowuje
tak później liczy sobie te duplikaty i wyświetla
tutaj zauważ taką rzecz że nigdzie nie reużywam jakiegoś strumienia zawsze
kiedy tworzę dany strumień na przykład jak tutaj to od razu robię na nim
jakieś interesujące mnie operacje oraz go finalizuje nigdzie ten strumień
nigdzie tu ani nie zwraca ani nie przekazuje jako parametr strumienia można potraktować
to jako taką praktykę z tego względu że w różnych elementach
w javie jeżeli otwieramy jakąś rzecz na przykład otwieram
połączenie do bazy danych otwieramy plik to też w tym samym miejscu na tym samym poziomie
na przykład tej samej metodzie dobrze jest zamknąć nasz element tak żeby
nie było takiej zależności okej ja tutaj przekazuję otworzyłem i przekazuję jakiś
element na przykład tutaj ten string i ktoś go zamknie albo
ktoś inny będzie zakładał że on nie został wcześniej zamknięty tak i
teraz zauważ że te elementy mógłbym liczyć duplikaty niezależnie
od tego jaką tutaj listę podaję tutaj możemy utworzyć
i więcej metod jakąś lambdę tutaj użyć i moglibyśmy
odfiltrowywać na przykład nie wiem tylko te parzyste nieparzyste i wśród
nich liczyć duplikaty więc tu jest takie oddzielenie się tych konceptów okej teraz
przejdźmy do bardziej zaawansowanego przykładu okej tutaj mamy
równie ambitną domenę nawet prawie tą samą też liczenie duplikatów
tylko przeniesioną jako oddzielną jakąś klasę no i tutaj teraz spróbujmy
sobie poczytać co tu się dzieje my mamy między innymi metodę get duplicates tak
mamy jeszcze taką metodę get duplicates map jej
założeniem jest zwrócenie mapy w niej są jako klucze są duplikaty
oraz ich liczba tak okej mamy
też get without duplicates czylii po prostu dostajemy jakby seta
z tego z tej kolekcji praca z tą klasą wygląda tak że tworzymy
sobie najpierw ten duplicates counter ta nazwa jest taka
taka sobie trochę dajemy mu listę on tutaj coś
robi i widzimy trochę coś dziwnego trochę okej i później
możemy wywoływać poszczególne metody no okej zobaczymy sobie
jak działa w praktyce no okej coś tu działa teraz
przyjrzymy się tej klasie co tutaj możemy poprawić bo pierwsza
rzecz ten konstruktor jest trochę taki dziwny bo raz że zapisuje on tutaj tę listę
i to jeszcze można by było to było okej ale zapisujemy
strumień i jeżeli ktoś zapisuje strumień do
fielda jakiejś klasy to w większości przypadków będzie to coś
co nie powinno się wydarzyć raczej zauważ że ten stream który tutaj został
zapisany do field on jest wykorzystywany w kilku metodach tutaj
widzimy że tutaj jest robione jakieś distinct jakieś kolejne rzeczy są robione więc okej a
spróbujmy poza tym że odpaliliśmy sobie tę metodę tak to spróbujmy
odpalić ją jeszcze raz i tutaj mamy tą samą sytuację jaką mieliśmy w
przypadku metody tak ten strumień został zamknięty okej czyli
na pewno to czego musimy się pozbyć to tego tak tego elementu w
każdym miejscu powinniśmy raczej sobie utworzyć i trzymać się tego że tworzymy stream
robimy coś na nim zamykamy go zwracamy wynik i ten strumień mi po prostu znika
tak okej tutaj dalej i duplicates i tym bardziej get duplicates map tutaj
widzimy że trochę to mało czytelny z tego względu że jest dużo operacji
na strumieniu w jednej linii proponuję abyś trzymał się taki konwencji
że staramy się nie robić tego w jednej linijce chyba że to jest naprawdę bardzo krótkie
ale w miarę możliwości sobie to łamać tutaj są takie dwa podejścia albo
zostawiamy tą metodę która stworzyła strumień tak czy tam
powiedzmy jest wywołanie metody na jakimś obiekcie nieważne czy to jest stworzenie strumieni
i ją możemy sobie tutaj zostawić każda kolejna operacja jest łamana
tak ale możemy też sobie coś takiego zrobić tak ważne aby w całym
swoim code base starać się być w miarę takim spójnym tak pod tym względem
żeby były te konwencje dobra to sobie pewnie poprawimy tutaj
ja mam trochę zastrzeżeń takich nie widzę za dużo wartości
w tym że my dodajemy tę listę tworzymy jakiś obiekt i okej wydaje
mi się że miałoby to sens wtedy gdyby ta lista była naprawdę ogromna
i w tym tutaj konstruktorze żebyśmy sobie wyliczyli już jakieś statystyki tej
listy i je zatrzymali tutaj a tutaj byśmy tylko zwracali poszczególne wyniki tak
żeby nie było już tego narzutu przy wykonywaniu kolejnych tak
bo tutaj jak na przykład sobie wykonamy dwa razy get duplicate to poza tym że to
nie zadziała ze względu na ten stream który tutaj mamy to w założeniu by to za każdym
razem przeliczało te dane co było by trochę bez sensu więc ja bym przyjął takie
podejście że ta klasa mogłaby być taką klasą której nigdy nie
tworzymy instancji czyli zrobimy sobie prywatny konstruktor na przykład oraz
wszystkie metody tutaj wewnątrz będą statyczne oraz będą przyjmowały tą listę dla której
ma być wykonana operacja okej zobaczmy jak to będzie wyglądało po reflektorze już
na pierwszy rzut oka mi to wydaje się trochę takie bardziej przyjemne do czytania po pierwsze mam prywatny
konstruktor tak czyli nie mamy żadnego stanu wewnątrz tej klasy za każdym razem kiedy
chcemy coś zrobić po prostu wywołujemy metodę tutaj z tym parametrem i poza
tym żadny stan nie jest przekazywany kolejną rzeczą którą tutaj poprawiliśmy są te wcięcia
tak żebyśmy nie mieli dużo elementów operacji w jednej linii
kolejną rzeczą którą zrobiłem to jest to że pozbyłem się tutaj zmiennej
lokalnej pokażę ci jak to wyglądało tutaj mieliśmy zmienną lokalną
na który później od razu odpalaliśmy kolejny set i
stream teraz po prostu spiąłem to w jedną całość i dzięki temu możemy czytać
tę metodę od góry do dołu i po prostu widzimy po kolei co się
działo z tymi elementami one na początku były strumieniem
tak później znowu były tak jakąś kolekcją później na niej zrobiłem values
znowu strumień w każdym razie widzimy jak to płynie mniej
więcej prawda ok kolejną rzeczą jest to że tutaj get duplicate
teraz zwraca seta z tego względu że wydaje mi się że semantycznie
set bardziej pasuje do opisywania tego jakie są duplikaty
ponieważ założenie jest takie że ta metoda zwróci elementy które się nie
powtarzają tak po prostu po jednym duplikacie dostaniemy tak samo
dostaniemy tutaj get without duplicates zwróci seta tak na którym później
możemy z niego stworzyć jakąś inną no i tutaj już nie używam stream
distinct i później znowu collect tylko od razu robię hash set zawsze
tak nie zawsze wykorzystywanie strumieni zwiększa czytelność
jeszcze jedno może taką wydaje się małą rzeczą ale
po prostu zmieniłem nazwę tej klasy tak duplicate support
wydaje mi się lepszą nazwą niż duplicates counter
w tym momencie szczególnie kiedy tutaj niektóre elementy
jak get without duplicates to mi się tak nie wydaje że odpowiedzialnością
klasy duplicates counter jest zwracanie jakichś kolekcji bez
duplikatów no to jest takie takie dziwne okej zmieniłem też nazwę
tutaj parametrów typu generycznego e jak element
tak tak samo w liście jest tak samo tak jak mówiłem tutaj mamy metody
statyczne prywatny konstruktor praca z tą klasą wydaje mi się teraz
jest dużo lepsza możemy sobie zobaczyć jak wygląda jej wykorzystanie tak nie
robimy żadnego tworzenia jakiejś dziwnej klasy po prostu wołamy poszczególne metody z
parametrem tak nie mam żadnego stanu pomiędzy w tej krótkiej rozgrzewce zdążyliśmy
się nauczyć kilku ważnych rzeczy po pierwsze starajmy się nie projektować tak
naszych klas i metod aby sprzyjało to błędom związanym z użyciem
już zamkniętego strumienia to znaczy starajmy się nie dopuszczać
do takich sytuacji kiedy strumień jest field'em jakiejś klasy oraz nie
umieszczajmy strumieni jako parametry bądź element zwracane z metod kolejną
rzeczą jest dbanie o czytelność lambd oraz operacji na strumieniach starajmy się łamać
te operacje w naszym code base tak wspójnie starajmy się
jeżeli nie musimy to nie wykorzystywać jakiś zmiennych lokalnych tak tylko
żeby od początku do końca był na przykład jeden strumień bądź jeden
łańcuch operacji tak kolejną rzeczą jest to abyśmy starali się wykorzystywać
możliwość podania uchwytu do metody zamiast lambdy oraz
żebyśmy starali się nie używać blokowych tych lambd tak te lambdy wieloliniowe
zamiast tego zamknijmy to sobbie jakąś metodę tę referencje do tej metody po prostu
podajmy w miejsce gdzie podawaliśmy lambdę to będzie się
dużo przyjemniej czytało taką ostatnią wagą w tej lekcji jest
to że nie musimy zawsze używać strumieni lambd tak zamiast tego możemy
po prostu to sobie wyeksponować w jakiejś innej metodzie tak jakiś fragment
zamiast kombinować jak tutaj zrobić coś na strumieniu to zróbmy to po prostu
po swojemu to jest prostsze tak to tyle
w tej lekcji a w kolejnej lekcji dowiemy się czy rzucanie wyjątków w
lambdach i w strumieniach jest bezpieczne czy nie czy to jest okej oraz to
jak bezpiecznie korzystać z zewnętrznych zasobów takich jak jakaś
zmienna jakieś kontenery jakieś metody wewnątrz lambdy w strumieniu dzięki
wielkie i do zobaczenia