Author Archive Kamil

ByKamil

Bazy danych w Javie

Jak zaznaczyliśmy wcześniej podczas omówienia podstawowych operacji na plikach jedną z potrzeb programów komputerowych jest utrwalanie przetworzonych danych. Do niektórych zastosowań wystarczające są pliki, czasem są wręcz wygodniejszą formą archiwizacji. Jednakże gdy danych jest dużo wygodniejszą opcją może być wykorzystanie bazy danych.

Read More

ByKamil

Eclipse rozwiązanie problemu z konfiguracją

Czasami może się zdarzyć, że próbujemy uruchomić Eclipse, ale zamiast załadowania naszego obszaru roboczego wita nas nieprzyjemny komunikat, który brzmi.

A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No Java virtual machine was found after searching the following locations: C:/Java/jdk-13.0.2/bin

Read More

ByKamil

Jak ustawić ciemny motyw w Eclipse

Wśród użytkowników komputerów oraz smartfonów oraz większą polarnością cieszą się ciemne motywy. Nic zatem dziwnego, że coraz więcej witryn internetowych, aplikacji, a nawet całe systemy operacyjne pozwalają zmienić kolorystykę na ciemniejszą. Dlaczego twórcy wręcz prześcigają się w udostępnianiu ciemnych skórek w swoich aplikacjach? Poniżej postaramy się odpowiedzieć na to pytanie. Na koniec opiszemy jak w prosty sposób ustawić motyw w IDE Eclipse.

Read More

ByKamil

Wątki w Javie – programowanie współbieżne

Pojęcie wielowątkowości jest od dawna znane użytkownikom komputerów. Od wielu lat na rynku występują procesory wielordzeniowe, które pozwalają na pracę kilku procesów systemowych na raz. Jednakże w czasach, kiedy nie były one standardem również istniała współbieżność – była imitowana przez wywłaszczanie procesów i przyznawanie czasu pracy procesora innemu.

Procesy

Proces jest elementem systemu operacyjnego, który służy do organizacji wykonywania programu tak, aby dostępne były odpowiednie zasoby np. procesor, pamięć. Ważną cechą jest to, że każdy proces posiada swoje dane, identyfikator (PID). W związku z tym w przypadku aplikacji wieloprocesorowej wymagana jest komunikacja między nimi.

Wątki

Wątki w odróżnieniu od procesów są dużo lżejsze i są ich częścią. W procesie musi być uruchomiony minimum jeden wątek, ale może być ich więcej.

Główną różnicą jest to, że zasoby są współdzielone między wątkami w wewnątrz jednego procesu. Daje to rozmaite korzyści np. skrócenie czasu oczekiwania na wykonanie zadań aplikacji. Wielowątkowość nie jest jednak pozbawiona wad i jedną z nich jest problem spójności danych. Aby temu zapobiec należy synchronizować pracę wątków, co może przysporzyć sporo problemów.

Uruchomienie kilku wątków jest niezbędne w przypadku bardziej złożonych aplikacji. Wyobraźmy sobie aplikację typu przeglądarka internetowa. Zazwyczaj użytkownik przegląda różne strony internetowe, pobiera pliki, słucha muzyki, która jest puszczana z karty w tle. Dzieje się tak dlatego, że przeglądarka jest aplikacją wielowątkową. Gdyby było inaczej nawet ściąganie plików zablokowałoby jakąkolwiek możliwość ingerencji w działanie programu – nawet zamknięcia aplikacji.

Tworzenie wątków

Technicznie tworzenie nowych wątków jest prostym zadaniem. Wymagane jest jedynie kilka czynności.

Utworzenie klasy

Zaczynamy od utworzenia prostej klasy implementującej interfejs Runnable.

Uruchomienie wątków

Gdy mamy już klasę implementującą interfejs Runnable wystarczy utworzyć obiekty, a następnie przy ich pomocy obiekty klasy Thread. Następnie uruchomić wątek przy pomocy metody start().

Przykładowy program

Wyobraźmy sobie program, który posiada kilka funkcjonalności i każda do swojego wykonania zajmuje określoną ilość czasu procesora. W naszym przykładzie będą to czasy 1000, 500 i 100 ms. Ma to na celu pokazanie, że różne procedury mogą wymagać innej ilości czasu do wykonania. Równie dobrze pierwsza operacja mogłaby wymagać znacznie więcej czasu, a dwie pozostałe tyle samo. Dzięki zastosowaniu wątków te krótkie operacje mogą być wykonane równocześnie i nie trzeba czekać na wykonanie tej pierwszej – najdłuższej. Ma to znaczenie w przypadku graficznego interfejsu użytkownika, gdy nie może on wcisnąć przycisku zatrzymania operacji.

W klasie ThreadTest będziemy przechowywać nr wątku oraz czas wykonywania operacji w nim zawartej. W rzeczywistości żaden wątek nic nie będzie robił. Oczekiwanie ma za zadanie symulację wykonywania jakiegoś algorytmu. Wykonamy je metodą sleep z klasy Thread.

Jak widać nie trzeba bezpośrednio wywoływać metody run. Jest ona uruchamiana po wywołaniu metody start. Przykładowym wynikiem uruchomienia programu może być następująca.

Wątek nr 1, który trwa najdłużej nie blokuje programu i równolegle wykonują się pozostałe wątki. Następnie czeka znowu na czas procesora i wykonuje się ponownie.

ByKamil

Losowość w Javie – klasa Random

Losowość jest powszechnie występującym zjawiskiem w naszym życiu codziennym. Elementy losowe od zawsze stanowiła źródło rozrywki dla ludzi czego dowodem jest towarzyszący od wieków hazard. Nie inaczej jest dziś, choć losowość ma znaczenie także w mniej kontrowersyjnych rozrywkach takich jak gry komputerowe oraz coraz bardziej popularne gry planszowe.

Read More

ByKamil

Operacje na tablicach w Javie

We wcześniejszych częściach szkolenia poznaliśmy już zarówno tradycyjne tablice, jak i ich dynamiczne odpowiedniki w postaci klasy ArrayList. Do tej pory mamy opanowane umiejętności, takie jak deklarowanie i inicjowanie nowej tablicy oraz dostęp do elementów poprzez operator []. W tej lekcji przyjrzymy się bliżej klasie Arrays, która dostarcza szeregu przydatnych metod do pracy z tablicami.

Read More

ByKamil

Obsługa plików w Javie

Programy, które do tej pory pokazywaliśmy zawsze przetwarzały pewne dane natomiast natychmiast po zakończeniu ich wykonywania dane bezpowrotnie przepadały. Jednym ze sposobów utrwalenia wyników działania aplikacji jest zapis do plików. Możemy również wykorzystać je jako źródło danych do przetworzenia w programie. Java udostępnia narzędzia niezbędne do obu tych czynności. Gdy danych jest zwyczajnie dużo dobrym pomysłem może się okazać użycie baz danych. W poprzedniej części przyjrzeliśmy się optymalizacji łańcuchów znakowych przez klasę StringBuilder.

Read More

ByKamil

StringBuilder i StringBuffer w Javie

Przetwarzanie danych tekstowych należy do jednych z ważniejszych elementów pracy przy komputerze. Na początku naszego szkolenia już wspominaliśmy o klasie String. Nadszedł czas na nieco szersze ujęcie problemu łańcuchów znakowych – bardziej od strony technicznej.

Read More

ByKamil

Implementacja listy jednokierunkowej w Javie

Implementacja listy jednokierunkowej w Javie

Nasza lista jest zbudowana z dwóch klas.

  • Wezel – klasa wewnętrzna – reprezentuje pojedynczy węzeł na liście.
  • Lista – klasa zewnętrzna – zawiera algorytmy dodawania, usuwania oraz wyświetlania elementów oraz przechowuje pierwszy element listy.

Aby pokazać różnice pomiędzy listami dwukierunkowymi a jednokierunkowymi postanowiliśmy opracować własną implementację. Ponownie naszym celem jest pokazanie działania tej struktury danych, a nie możliwości interfejsów, takich jak Comparable lub Iterable. Aby maksymalnie uprościć kod przechowywanym typem danych będzie int.

Naszym celem było napisanie jak najprostszego algorytmu, aby pokazać jak operować na listach jednokierunkowych. Tak, aby w praktyczny sposób przekazać wiedzę z naszego teoretycznego wstępu odnośnie list jednokierunkowych. Na pierwszy rzut oka implementacja jest bardzo podobna do listy dwukierunkowej, jednakże w przypadku usuwania węzła jesteśmy zmuszeni utworzyć tymczasową zmienną, która będzie go przechowywać. W przeciwnym wypadku stracimy możliwość np. zmiany referencji w poprzednim ogniwie listy, gdyż aktualnie usuwany element „nie zna” położenie swojego poprzednika.

Aby uruchomić poniższy kod należy skopiować kod, a następnie skompilować.

Wewnętrzna klasa Wezel

Powyższy program można podzielić na dwie części. Pierwszą jest obiekt, który przechowuje dane i jest nią klasa Wezel. Ze względu na to, że ta struktura danych jest mało elastyczna umieściliśmy ją wewnątrz klasy Lista, gdyż i tak nie wykorzystamy jej nigdzie indziej. Takie podejście jest wygodnie, ponieważ mamy ułatwiony dostęp do pól obu klas.

Pola

Obiekt klasy Wezel zawiera jedną referencję do kolejnego obiektu oraz zmienną przechowującą dane. Jeśli dany węzeł jest ostatni (ogon), to jego referencją na następny obiekt jest wartość null.

Konstruktor

Inicjuje dane – referencję do następnego obiektu na null, a pole z danymi uzupełnia wartością przekazaną w argumencie.

Zewnętrzna klasa Lista

Obiekt klasy Lista przechowuje referencję do pierwszego elementu listy, czyli głowę (ang. head). Zawiera również niezbędne algorytmy, takie jak:

  • dodawanie elementów do listy,
  • usuwanie elementów z listy,
  • szukanie elementu o konkretnym indeksie,
  • wypisanie wszystkich elementów listy.

W metodzie main znajduje się przykładowy przebieg programu. Wykonanie metody main spowoduje wyświetlenie następujących komunikatów w konsoli.

Zachęcamy do eksperymentów z kodem.

Metody

Podstawową różnicą między implementacją listy dwukierunkowej jest algorytm usuwania elementu. Żaden węzeł nie zna położenia swojego poprzednika zatem przy przechodzeniu listy musimy utworzyć zmienną pomocniczą, którą będzie przechowywała jego referencję.

Czemu jednak nie postąpić jak w  przypadku list dwukierunkowych i do zmiennej pomocniczej nie użyć po prostu argumentu n-1? Przecież byłoby to dużo wygodniejsze i kod zajmowałby mniej linii. Powodem jest wydajność. Zwróćmy uwagę, że metoda getWezel() byłaby wywołana dwa razy – raz z argumentem n, a za drugim razem n-1. Jednakże dwukrotnie przejście przez listę zaczynałoby się od głowy listy. Oznacza to podwojenie liczby wykonywanych operacji. W przypadku małej kolekcji oczywiście nie ma to znaczenia, ale kolekcja może składać się z bardzo wielu elementów.

Wyjątek IndexOutOfBoundException

Jeżeli spróbujemy wpisać do metody szukającej indeks ujemny lub spoza naszej listy zostanie wyrzucony wyjątek.

System zbierania nieużytków (ang. Garbage collector)

W Javie nie ma potrzeby ręcznego czyszczenia pamięci. Jeśli nie mamy już referencji do obiektu, to nie musimy z tym nic robić. System zbierania nieużytków oczyści pamięć ze zbędnych obiektów.

ByKamil

Klasy osłonowe w Javie

Klasy osłonowe (ang. wrapper class) pojawiły się w szkoleniu już wcześniej. W ostatnim wpisie dotyczącym klasy Object okazało się, że gdy utworzymy uniwersalny kontener w postaci tablicy typu Object mimo wpisania wartości 1 (typ prosty int) program pokazał, że element jest obiektem klasy Integer.

Read More