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 opowiemy sobie trochę o mapach zacznijmy
od takiej najczęściej używanej implementacji map jest to po prostu hashmapa
jak nazwa wskazuje przy wrzucaniu i wyciąganiu elementów z tej mapy
jest wykorzystywany hash code a co za tym też idzie equals pewnie też okej
i do takiej mapy po prostu wrzucamy z putem naszą wartość
i ona zostanie zaindeksowana pod takim
kluczem tak czyli zostanie wrzucona pod takim kluczem i jeżeli zapytamy znowu
teraz wykorzystując geta z takim kluczem to dostaniemy na przykład z powrotem te wartość
tak tak to tak działa właśnie może tutaj też sprintować teraz że
te elementy są w środku tak tutaj w stringu okej i tak
wrzucone element możemy sobie wyciągać właśnie wykorzystując stringa i wykorzystując
metoda get to działa w ten sposób że jeżeli tutaj nie
dostaniemy powiedzmy żadnego elementu czyli powiedzmy nie ma takiego elementu
który jest wrzucony pod takim kluczem dostaniem po prostu nulla
w tym miejscu jeżeli chcemy dostać jakąś inną wartość jeżeli nie
znajduje się dany klucz w mapie to możemy ją tutaj sobie wstawić wykorzystując
get or default z tym nie ma takiego geta który zwraca optional ale
możemy sobie to opakować wszystko optional of nullable nie jesteśmy
w stanie przejść bezpośrednio z mapy na stream tak na api stream'owe
ale możemy wykorzystać sobie entryset który zwraca po prostu set zawierający
entry czyli powiedzmy takie pary klucz wartość w tym momencie jeżeli mieliśmy mapę
od string do integer to tutaj możemy sobie zobaczyć że entryset zwraca nam
seta od entry który string integer tak czyli
powiedzmy w pierwszej części będzie w tym entry będzie właśnie klucz a w drugiej
części będzie integer tak no i z tego możemy już setu
bezpośrednio na stream możemy przejść później możemy coś zmapować i możemy
zrobić collect do czegoś co tam już sobie chcemy prawda jak tam pokazywałem
poza entryset mamy jeszcze keyset oraz values
w ten sposób możemy łatwo uzyskać jakąś kolekcje na przykład listę
jeżeli chcemy mieć to właśnie w jakiejś liście wszystkich wartości danego
znajdujące się w danej mapie oraz wszystkich kluczy znajdujących
się w danej mapie jak widzimy mamy klucze i mamy wartości jeżeli mamy
jakąś listę na przykład czy jakąś inną kolekcję z której
jesteśmy w stanie przejść na api stream'owe i chcemy na przykład sobie stworzyć
na przykład jakąś mapę chcemy sobie na przykład stworzyć mapę która będzie zawierała przykładowo
dane słowo tak tutaj mamy jakieś słowa chcemy mieć
słowo jako klucz w mapie oraz chcemy mieć jego długość
w tej mapie jako wartość to możemy wtedy wykorzystać collect i
i tutaj podać collector to map w pierwszym parametrze tego to to map podajemy
w tym momencie function identity czyli po prostu on zwraca
taką lambdę function który dostaje wartość i tę samą wartość zwracan
w ten sposób przemapujemy sobie klucze tak pierwszy parametr
to jest mapper dla kluczy i w kluczu wylądują same słowa a później
podajemy funkcję która dostając poszczególne słowa tworzy
dla nich wartość która znajduje się w tej mapie tak czyli to jest po prostu wywołanie
length na stringu który się znajduje tak który jest słowem tak i w ten
sposób możemy sobie łatwo to jakoś właśnie zamienić na mapę tak a jakiś
taki powiedzmy właśnie klucz wartość tak jak nam to wychodzi tak
opierając się na wartościach znajdujących się w danym stream'ie trochę
innym ale często też pojawiającym się zadaniem jest zgrupowanie to
znaczy mamy powiedzmy ileś tam jakichś obiektów tak
i chcemy je pogrupować w jakieś właśnie powiedzmy bucket'y jakieś tak
powiedzmy że chcemy ze sobą teraz zgrupować wrzucić do jednej powiedzmy
pod jedno pole w mapie wszystkie słowa które tej samej długości czyli
będzie mieli foo i bar jako jakąś kolekcję znajdującą się pod kluczem
3 tak i rocket i online pod kluczem 5 tak
możemy do tego sobie wykorzystać collector grouping by i w grouping by
jako pierwszy parametr podajemy tutaj funkcję która wylicza
coś co będzie kluczem w mapie tak i on później już odpowiednio to
sobie zbiera i pakuję do mapy tak jako bucket'y no i tutaj mamy właśnie
taką można też powiedzieć że to jest pewnego rodzaju multimapa czyli mapa
która pod danym kluczem zawiera wiele wartości tak poza hash map
i samym interfejsem map mamy jeszcze implementację tree map który implementuje
sorted map oraz navigable map które dają dodatkowe możliwości
do interfejsu map oba te interfejsy są w stanie
zatrzymać powiedzmy pewną sekwencje to znaczy one
w momencie kiedy wrzucamy do tych map tutaj pod spodem znajduje się implementacja
wykorzystująca drzewa ona w sobie sortuje te elementy odpowiednio je
układa i później łatwo jesteśmy w stanie wyciągnąć sekwencje posortowaną z niej
w ten sposób powiedzmy tracąc trochę czasu przy wstawianiu tych elementów zobaczymy
sobie teraz co dają nam te interfejsy na pierwszy rzut oka te mapy
działają dokładnie tak samo w końcu sorted map dziedziczy po map tak
więc normalnie możemy zrobić put normalnie możemy zrobić get ale
poza tym mam jeszcze kilka innych możliwości dzięki temu że to
co przechowujemy w tree map czy w sorted map tak
ona jest świadoma powiedzmy kolejności tych elementów
w sensie powiedzmy jak one by się posortowały tak z tego względu to wszystko
tutaj wrzucamy jako klucze musi mieć powiedzmy musi implementować
albo comparible albo tworząc stream'a tutaj możemy podać komparator
który musi zostać dostarczony tak on inaczej nie byłby w stanie tego
wewnętrznie sortować sobie i układać w tym drzewie i dzięki temu jesteśmy
w stanie na przykład wyciągnąć pierwszy klucz i ostatni klucz tak powiedzmy dzięki temu że
jest zachowane to sortowanie to po prostu bierze pierwszy i ostatni element tak
czyli dziesiątkę i piątkę tym momencie później jak zobaczymy jeżeli nie używamy
sorted mapa a navigable map czyli powiedzmy trochę bogatszego interfejsu to jeszcze możemy wyciągnąć
first i last entry czyli dostaniemy całą parę wtedy poza
tym możemy robić jeszcze tail map i headmap na takiej mapie i w ten
sposób powiedzmy brać sobie wszystkie wartości w tej mapie zaczynając
na przykład od początku tego klucza tak lub do tego
klucza tak pamiętajmy już tam wszystko jest posortowane więc znowu nie ma problemu
tak i w tym momencie jak odpytamy z jedynką no to tutaj jeżeli zrobiłem tail
map to dostaniemy jedynkę i piątkę a jeżeli odpytamy z head
nap no to dostaniemy tylko wszystko to co było przed jedynką więc w tym momencie tylko wpisy
z minus 10 tak teraz jak pozmienimy sorted map na
navigable map to mamy jeszcze dodatkowe możliwości między
innymi możemy na przykład dla danego klucza dostać najbliższy klucz
w jedną bądź w drugą stronę czyli właśnie lower entry lub higher entry poza
tym że dostajemy tutaj właśnie cały wpis to możemy jeszcze spytać na przykład
jeszcze o klucz tak po uruchomieniu przykładu widzimy że dla piątki lower entry
dostaliśmy po prostu wpis 1 i wartość foo tak
a dla piątki higher entry no już tutaj wyżej niż piątka
nic nie ma w tej mapie wrzuconego więc dostaniemy null w tym momencie tak dodatkowo
możemy jeszcze zrobić coś z się nazywa floor entry lub na przykład
ceiling antry tak i to nam zwróci najbliższą
tutaj w przypadku floor od spodu wpis który jest mniejszy
bądź równy tutaj jak podajemy czwórkę na przykład
tak to dostaniemy w tym momencie jedynkę bo ona jest najbliższa tak
jeżeli wpiszemy na przykład na przykład piątkę no to wtedy dostaniemy piątkę no
bo po prostu mamy taką wartość wpisaną jeżeli byśmy na przykład wpisali
tutaj jeszcze minus 11 to w ogóle dostaniemy null w tym momencie
bo nie ma już niczego od spodu najbliższego do minus
11 a samego wpisu minus 11 też nie mamy tak tutaj
widzimy jak to działa w większości przypadków raczej będziesz wykorzystywał
hashmap czasami zdarza się jednak że te wartości które wrzucamy
do mapy nie tylko mają zależność tak jakby że klucz trochę wynika
na przykład tej wartości którą wrzucamy ale że klucze między sobą mają jakąś
zależność tak jak tutaj mieliśmy na przykład że razem da się ustawić je
na jakiejś powiedzmy skali tak no i powiedzmy jeżeli mamy na przykład
możemy mieć taką sytuację na przykład że wrzucamy do jakiejś tree mapy
do jakiegoś navigable map na przykład wartości po
czasie jej wystąpienia i wtedy moglibyśmy chcieć na przykład dla danego
czasu wystąpienia dostać najbliższą powiedzmy
najbliższy event tak czy jakieś wydarzenie i na przykład od danego wydarzenia
jeszcze kolejny najbliższe wydarzenie tak no i wtedy wykorzystałem
właśnie sorted bądź navigable map tak okej ale
jeżeli nie mamy takiej potrzeby żeby między tymi wartościami jakoś przeskakiwać
sobie jakoś właśnie tak cwanie między nimi chodzić po tej skali no
to wtedy wykorzystujemy po prostu hashmap ok to wszystko co chciałem ci pokazać w
kontekście map dzięki wielkie i do usłyszenia