Od zera do aplikacji developera – Znaki tekstowe [#03]

simplecoding.pl 7 lat temu

Cześć, to już trzecia część dzisiejszego kursu. Wiemy, iż dla komputera wszystko to zera i jedynki. Cóż, dla użytkownika niekoniecznie. Często chcemy pokazać jakiś komunikat, opisać wynik operacji… występuje dużo przypadków użycia, mógłbym pisać w nieskończoność. Większość języków programowania znaki tekstowe i całe łańcuchy znaków obsługuje bezproblemowo. Nie inaczej jest w przypadku Javy.

Pojedyncze znaki tekstowe – char

Krok po kroku, zaczniemy od omówienia pojedynczych znaków tekstowych. W Javie za przechowywanie pojedynczych znaków odpowiada typ prymitywny char. Nie jest on klasą, definiujemy go podobnie, jak prymitywne typy liczbowe. Różnica jest taka, iż wartość zmiennej bierzemy w znaki apostrofu. Przykładowe definicje znanych Ci literek.

Mówiłem Ci ostatnio, jak przechowywane są liczby. Pomogę Ci zrozumieć też, jak przechowywane są znaki. Pojedyncze znaki to nic innego jak odpowiedni kod Unicode, a więc każda literka, a adekwatnie znak, mają odpowiadający sobie kod. Można zatem powiedzieć, iż znaki też są liczbami Co to oznacza? Oznacza to, iż możesz definiować znaki też jako odpowiedni kod. Może to być zapis dziesiętny z prefixem \u lub choćby zapis szesnastkowy. Przy zapisie z ‘\u’ warto zaznaczyć, iż musi być to liczba, która posiada cztery cyfry. Co w przypadku, gdy liczba normalnie nie ma tych 4 cyfr? Dodajemy na początku zera. Przykładowo dla literki ‘g’ będzie wyglądać to tak:

Znaki specjalne

Czasami zdarzy się tak, iż potrzebujemy użyć innego znaku, np apostrofu. Deklaracja takiego znaku może się wydać dziwna, no bo jak to tak, apostrof w apostrofy… Zawsze możesz użyć odpowiedniego kodu, ale przyznaj, nie jest to zbyt czytelne. Ten problem na szczęście łatwo obejść. Są znaki specjalne, które możemy zadeklarować poprzez wpisanie ‘\znak’. Przykładowo więc, apostrof lub “backslash” zadeklarujemy tak:

Są też znaki, które – można powiedzieć – nie są do końca dla nas widoczne, na przykład znak nowej linii lub tabulacji, kody tych znaków to:

  • \t – znak tabulacji
  • \b – znak usuwania
  • \n – znak nowej linii
  • \r – znak powrotu “karetki” (migającego kolegi w konsoli)

Z ciekawostek, nie możesz zdefiniować “tekstowo” pustego znaku. Istnieje jednak odpowiedni unicode – 0000.

Większa ilość znaków

Nie zawsze jednak będziesz bawić się w deklarowanie pojedynczych znaków… generalnie, może być tak, iż nie będą Ci one specjalnie potrzebne. Dochodzisz do momentu, iż chcesz zdefiniować dzięki zmiennej cały komunikat. W tym celu w Javie istnieje klasa – nie typ prymitywny – która nazywa się String, z angielskiego łańcuch. Jest to po prostu tablica znaków (intuicyjnie – jeden tekst = zero, jeden lub więcej znaków). Deklarujemy go bardzo podobnie jak pojedyncze znaki, poprzedzając zmienną odpowiednim typem oraz biorąc tekst w cudzysłów. Konwencja w Javie jest taka, iż nazwy klas są pisane z DUŻEJ litery. Przykładowe deklaracje mogą wyglądać tak:

Co w przypadku znaków specjalnych w takim łańcuchu? Wystarczy poprzedzić taki znak dzięki ‘\’, tak jak pisaliśmy to wyżej.

Operacje na łańcuchach

Idźmy krok dalej. Wątpię, iż zadowoli Cię wyświetlanie tekstu, który w żaden sposób potem nie ulegnie zmianom. Poniżej jest program, który wykorzystuje pare przydatnych metod, które posiada klasa String:

Omówmy to po kolei na tym przykładzie:

  • zaczynamy od tekstu “Start! “ (zwróć uwagę na 3 spacje na końcu)
  • sprawdzamy, czy faktycznie białe znaki nie są ignorowane poprzez użycie metody length(), która zwraca nam długość łańcucha. Otrzymana wartość – 9. Start – 5 znaków, wykrzyknik to kolejny jeden oraz trzy białe znaki. Zgadza się
  • sprawdzamy, jaki znak znajduję się na miejscu z indeksem 1. Jest to litera ‘t’. Dlaczego nie ‘S’? W Javie oraz w wielu innych językach programowania, indeksy zaczynają się od cyfry 0, nie od 1, dlatego na miejscu 0 byłaby litera ‘S’, a na miejscu 1 jest litera ‘t’. O indeksach więcej następnym razem
  • za pomocą metody trim() usuwamy zbędne białe znaki na końcu, dlatego nasz nowy łańcuch (nowy, nie ten sam, ale o tym dalej) będzie krótszy niż poprzedni. Sprawdzamy to metodą length(). Wynik otrzymany – 6
  • następnie chcemy wyświetlić tylko pierwsze 3 znaki łańcucha. W związku z tym, używamy metody substring, której pierwszym argumentem jest indeks, od którego zaczynamy (w tym przypadku 0) oraz indeks PRZED KTÓRYM KOŃCZYMY, a nie na którym. Bierzemy więc przedział [0;3), czyli 0 – S, 1 -t, 2 – a.
  • jak zastąpimy poszczególne znaki w łańcuchu? Bardzo prosto. Używamy metody replace(), która przyjmuje kolejno znak, jaki chcemy zastąpić oraz znak, jakim chcemy zastąpić. Tutaj zastępujemy WSZYSTKIE wystąpienia litery ‘t’ literą ‘w, dlatego otrzymany tekst to Swarw!
  • gdzie leży pierwsza litera ‘w’? metoda indexOf() prawdę nam powie. Zgodnie z tym, jak indeksujemy, w tym przypadku zwrócona wartość to 1. Co, jeżeli dany znak nie występuje w łańcuchu? Metoda zwróci wtedy -1
  • cały tekst pisany dużymi literami? Dobrze, metoda toUpperCase() służy pomocą. o ile chcemy mieć tekst, który składa się tylko z małych liter to – jak się możesz domyślić – należy użyć metody toLowerCase()
  • chcemy połączyć tekst w jeden? Wystarczy użyć znaku dodawania w najprostszej wersji

Pewnie zastanawiasz się “dlaczego robisz tyle obiektów dla prostych operacji”? Cóż, już same operacje je robią. Stringi są Immutable, czyli są niezmienne. Każda operacja na łańcuchu tworzy nowy łańcuch, więc o ile chcemy korzystać ze zmodyfikowanego łańcucha, musimy go przypisać do nowej zmiennej lub nadpisać już istniejącą. Aby Ci to pokazać, na końcu wypisałem łańcuch początkowy. Co tam się pojawia? “Start! “

Sprawniejsze łączenie łańcuchów

Wspomniałem, iż najprościej łańcuchy połączyć dzięki znaku “+”. Niestety, nie jest to wydajne. O ile łączymy parę łańcuchów to nie ma aż takiego znaczenia, tak w przypadku dużej ilości takich operacji wydajnościowo możemy to odczuć. Java natomiast posiada dwie klasy, które sprawnie wykonują te operacje. Są to StringBuilder (asynchronicznie) i StringBuffer (synchronicznie). Każda z nich jest lepsza od zwykłej konkatenacji, natomiast gdy masz wybierać między nimi, wybierz StringBuilder, jest szybsza. Kolejny program i omówienie:

Po kolei:

  • na początku musimy zadeklarować buildera. Jeszcze rzeczy obiektowych nie omawiamy, ale w tym przypadku lekko muszę wtrącić. Nowe obiekty inicjujemy poprzedzając klasę słowem kluczowym “new”. W nawiasie na końcu natomiast podajemy do konstruktora argumenty. W tym przypadku mogę wykorzystać konstruktor bez argumentów, zaczniemy od pustego łańcucha. o ile znasz wartość początkową, możesz ją w tym przypadku podać jako parametr konstruktora
  • za pomocą metody append() dołączamy tekst “Hi”. Jesteśmy go w stanie standardowo wypisać. Jak to możliwe, skoro to nie jest ani String ani char? Wypisywanie tą metodą działa tak, iż wywoływana jest metoda toString() podanego obiektu (o tym niebawem). W StringBuilderze metoda toString() wypisuje obecną wartość budowanego łańcucha.
  • tą samą metodą dodajemy “, hello”, a więc mamy teraz “Hi, hello”
  • “Hi,” nam się znudziło. Usuwamy je dzięki metody delete() stosując tą samą zasadę jak przy metodzie substring() dla klasy String
  • może trochę więcej liter ‘l’ (małe L) w słowie “hello”? Dobrze, metoda insert() dodaje nam w miejsce podanego indeksu łańcuch, który podajemy jako kolejny argument. Na miejscu 2 mamy pierwsze wystąpienie litery l, a więc w to miejsce wstawiamy nasz łańcuch, a “to po prawej stronie” jest przesuwane za nasz dodawany element
  • tworzenie łańcucha zakończone, wydobędziemy go metodą toString()

Podsumowanie i zadanie domowe

Poszerzasz swój arsenał, jest nieźle. Dzisiaj dowiedziałeś się trochę o znakach w komputerze, łańcuchach znakowych oraz jak nimi manipulować. Dość łatwe, prawda? Daje nam to większe możliwości, szczególnie o ile chodzi o interakcję z użytkownikiem.

Myślę, iż kolejne zadanie dla Ciebie, nie będzie odbiegać poziomem trudności od poprzedniego. Różnica jest taka, iż bez zaglądnięcia tutaj możesz mieć drobne problemy.

Zadanie:

Na początku, stwórz dwie zmienne klasy String. Pierwsza z nich ma przechowywać twoje imię, druga nazwisko. W następnej kolejności, stwórz zmienną typu char, która będzie przechowywać pierwszą literę Twojego drugiego imienia. Stwórz też zmienną liczbową, która będzie zawierać informację o Twoim wieku. Korzystając z tych zmiennych:

  • wypisz swoje całe imię w postaci: “imię litera. nazwisko”, np Jan K. Kowalki
  • sprawdź, gdzie występuje po raz pierwszy litera “a” oraz “A” w twoim imieniu i nazwisku OSOBNO
  • zastąp wystąpienia litery “a” literą “e”
  • używając odpowiednich metod: wypisz “imię pierwsza litera nazwiska., lat x”, np “Jan K., lat 50”.

<- [#02] Liczby [#04] Tablice i listy ->

Idź do oryginalnego materiału