Artykuł

sxc.hu sxc.hu
gru 16 2008
0

Java - operacje na tekście

Możliwość korzystania z łańcuchów tekstowych jest niewątpliwie jednym z ważniejszych aspektów każdego języka programowania. Jest to podstawowy aspekt, który powinien znać po prostu każdy. W Javie operacje na tekście, w głównej mierze opierają się o klasę String. Zgodnie z konwencją tego języka, zmienna typu String posiada obiektowy charakter. Oznacza to, że jeśli tworzymy nową zmienną typu String, tak faktycznie tworzymy nowy obiekt klasy String. Dzięki takiemu podejściu możemy wykonywać różne metody i operacje, które zostały zdefiniowane w tej klasie. Poszczególnym metodom a także innym towarzyszącym klasom (StringBuilder, StringTokenizer, StringBuffer), przyjrzymy się w tym artykule

Tworzenie obiektów typu String

O tworzeniu obiektów typu String, była już mowa w artykule poświęconym właśnie zmiennym i obiektom, dlatego teraz tylko krótko przypomnę zasady.

Łańcuchy tekstowe w Javie są obiektami, dlatego musimy taki obiekt zadeklarować a potem utworzyć jego instancję:

String tekst;
tekst = new String("to jest jakiś przykładowy tekst");

W ten sposób utworzyliśmy łańcuch tekstowy w sposób typowo obiektowy. Programiści Javy doszli do wniosku, że ponieważ zmienne typu String będą używane bardzo często, taka konstrukcja jest uciążliwa. Dlatego w 99% przypadków spotykamy się z konstrukcją przedstawioną poniżej:

String tekst2;
tekst2 = "To jest ekspresowy String"
// można jeszcze szybciej, wszystko robimy w jednej linii!
String tekst3 = "Tym razem wszystko w jednej linii";

W takiej konstrukcji jak w linii czwartej powyższego listingu, zmienną tekst3, deklarujemy jak klasyczną zmienną. I tak właśnie powinniśmy myśleć, łańcuch tekstu jest zmienną, ale zmienną obiektową i stąd posiada nadprzyrodzone możliwości:)

Ważna uwaga: należy pamiętać, by łańcuchy tekstu zawsze brać w cudzysłów, nie apostrof, tylko cudzysłów!

Konkatenacja Stringów

Ten dziwnie, obco brzmiący termin oznacza nic więcej jak łączenie napisów. Operatorem konkatenacji jest znak plusa (+). Przedstawmy działanie operatora w praktyce:

String tekst1 = "Ala";
String tekst2 = "ma";
String tekst3 = "kota";
// Poleceniem print wyświetlamy każdą zmienną pokolei i dodajemy spacje między nimi
System.out.print(tekst1);
System.out.print(" ");
System.out.print(tekst2);
System.out.print(" ");
System.out.print(tekst3);

Powyższy przykład nie używa konkatenacji. Osiągnęliśmy zamierzony efekt. W jednej linii Java wydrukowała tekst Ala ma kota. Ale czy tak to miało wyglądać? Spróbujmy jeszcze raz:

String tekst1 = "Ala";
String tekst2 = "ma";
String tekst3 = "kota";
// Polecenie print od razu wyświetla jedną linię!
System.out.print(tekst1+" "+tekst2+" "+ tekst3);

No proszę. Wyrzuciliśmy cztery instrukcje System.out.print i zastąpiliśmy ją jedną. Prawdziwa oszczędność. Na dodatek powyższy napis dla Javy stanowi jedność, w poprzednim przykładzie był podzielony na pięć elementów. Oczywiście w powyższym przykładzie mogliśmy pominąć spacje (puste cudzysłowy) i wyświetlić trzy połączone zmienne. Konkatenacja umożliwia nie tylko łączenie zmiennych razem, ale np. także zmiennych i tekstu, który nie został zapisany w zmiennej. Przykład:

String tekst1 = "Ala";
System.out.println(tekst1+" ma kota, a kot ma Alę!");

Powyższy kod wyświetli napis: Ala ma kota, a kot ma Alę!

Kluczowe metody klasy String

Jako, że String jest zmienną obiektową, dlatego też możemy wykonywać na nim różne operacje i metody. Dostęp do metod scharakteryzowanych dla tej klasy następuje w standardowy sposób czyli przez użycie kropki .. Każda z przedstawionych tutaj metod zawiera oryginalną sygnaturę.

charAt

public char charAt(int index)

Metoda charAt zwraca nam określony znak, na który wskazuje index. Przykładowo, jeśli mamy słowo Witam, to składa się ono z pięciu znaków. Założmy że jako parametr metody charAt, przekazaliśmy 2, to w tym wypadku w wyniku otrzymamy literkę t (Nie jest to literka i jak niektórzy z was mogli sądzić, ponieważ Java zaczyna liczenie od zera). Przykład:

String tekst = "Witaj";
// poniższy zapis zwróci literkę t
System.out.println(tekst.charAt(2);

equals

public boolean equals(Object anObject)

Metoda equals pozwala na porównywanie dwóch Stringów. Moglibyśmy co prawda użyć podwójnego znaku równości, lecz w niektórych sytuacjach może to powodować błędy. A ponieważ String jest obiektowym typem więc używajmy metody equals. Przykład:

String tekst1 = "Ala";
String tekst2 = "Ala";
String tekst3 = "kot";
// otrzymamy wartość true:
System.out.println(tekst1.equals(tekst2));
// oczywiście poniższy wiersz da ten sam rezultat co wiersz powyżej:
System.out.println(tekst2.equals(tekst1));
// otrzymamy wartość false:
System.out.println(tekst1.equals(tekst3));

Jak zatem widzimy metoda equals zwraca wartość typu boolean. W wypadku gdy oba Stringi są równe w wyniku otrzymujemy prawdę (true), w przeciwnym wypadku fałsz (false). Kolejność porównywanie Stringów nie ma znaczenia. Oczywiście zamiast zmiennych możemy po prostu użyć tekst zapisany w cudzysłowie.

equalsIgnoreCase

public boolean equalsIgnoreCase(String anotherString)

Metoda o bardzo zbliżonym działaniu do przedstawionej wyżej metody equals. W tym wypadku jednak, funkcja nie zwraca uwagi na wielkość liter. Dlatego też, poniższy kod zwróci prawdę:

String tekst = "Tekst";
String tekst2 = "tEKST";
System.out.println(tekst.equalsIgnoreCase(tekst2));

startsWith

Metoda startWith występuje w dwóch, różnych przeciążonych wersjach:

public boolean startsWith(String prefix, int toffset)
public boolean startsWith(String prefix)

Generalnym założeniem metody startsWith, jest sprawdzenie czy dany String zawiera określony ciąg znaków. Dodatkowo szukany ciąg znaków musi pojawić się na samym początku łańcucha (wersja druga metody). Może jednak sprecyzować wartość toffset, która to wartość definiuje przesunięcie szukanego łańcucha o długość offsetu określoną w parametrze. Metoda zwraca true, gdy znajdziemy szukany ciąg, lub false w przeciwnym wypadku.

endsWith

public boolean endsWith(String suffix)

Metoda o zbliżonym działaniu do metody startsWith. W wypadku metody endsWith, szukamy jednak ciągu na końcu wskazanego Stringa.

substring

Metoda substring występuje w dwóch, różnych przeciążonych wersjach:

public String substring(int beginIndex)
public String substring(int beginIndex, int endIndex)

Metoda substring pozwala na wycinanie z naszego określonego łańcucha fragmentu tekstu. W pierwszej wersji metody podajemy numer indeksu początkowego, od którego wytniemy cały tekst do końca. W drugiej wersji podajemy indeks początkowy i indeks końcowy. Wytniemy tylko to, co znajduje się pomiędzy. (Wycinanie należy raczej rozumieć przez kopiowanie, struktura zmiennej nie ulega zmianie). Przykład:

String tekst = "Wielkopolska";
// Poniższy wiersz zwróci słowo: polska
System.out.println(tekst.substring(6));
// Poniższy wiersz zwróci słowo: pol
System.out.println.(tekst.substring(6,9));

length

public int length()

Funkcja length zwraca długość łańcucha tekstowego i przedstawia ją w postaci liczby typu integer. Ponieważ jest to naprawdę prosta metoda przejdziemy od razu do przykładu:

String tekst = "kajak";
// Poniższe polecenie wyświetli liczbę: 5
System.out.println(tekst.length());

concat

public String concat(String str)

Metoda reprezentuje obiektowe podejście do konkatenacji Stringów, którą opisałem wyżej w tym artykule. Metoda concat do podanego Stringu dodaje kolejny. Przykład:

String tekst = "Ala";
// Poniższa linia zwróci tekst: Ala ma kota
System.out.println(tekst.concat(" ma kota");

replace

public String replace(char oldChar, char newChar)

Metoda replace, pozwala na zamianę pojedynczego znaku w określonym Stringu na inny. Metoda ta zmienia wszystkie wystąpienia tego znaku. Przykład:

String tekst = "kajak";
// Poniższe polecenie zamienia litery k na p i drukuje napis: pajap
System.out.println(tekst.replace("k", "p"));

split

Metoda split występuje w dwóch, różnych przeciążonych wersjach:

public String[] split(String delimeter, int limit)
public String[] split(String regex)

Metoda split pozwala na rozdzielenie Stringu wejściowego według określonego separatora. Separatorem może być dowolny znak, a z reguły są to następujące znaki: :, ; i | (może to być również spacja). Druga wersja metody pozwala na zdefiniowanie ilości iteracji. W takim wypadku dzielenie łańcucha będzie mogło wystąpic maksymalnie tyle ile wynosi wartość zmiennej limit. Poszczególne elementy trafią do tablicy tekstowej (o tworzeniu tablic była mowa w artykule poświęconym zmiennym). Przykład:

String tekst = "Ala:ma:kota:a:kot:ma:Ale";
String wynik1[] = null;
String wynik2[] = null;
// Do tablicy wynik1 trafi zawartość zmiennej tekst 
// podzielona na elementy: Ala, ma, kota itd.
wynik1 = tekst.split(":");
// Do tablicy wynik2 trafi zawartość zmiennej tekst 
// podzielona na 2 elementy: Ala, ma:kota:a:kot:ma:Ale itd.
wynik2 = tekst.split(":", 2);

trim

public String trim()

Funkcja trim pozwala na usunięcie białych znaków z końca i początku wprowadzonego Stringu. Warto jej użyć, gdy pobieramy jakieś dane od użytkowników.

Powyżej przedstawiłem metody klasy String, których używa się najczęściej i są najbardziej praktyczne. Oczywiście takich metod jest znacznie więcej. Ze szczegółową listą wraz z opisami, można spotkać się na oficjalnej stronie Javy.

Konwersje typów

W Javie możemy dokonać konwersji innego typu na String. Najłatwiej tego dokonać używając konkatenacji. Przykłady:

int liczba_int = 12;
int liczba_double = "5.0";
String string_int = ""+liczba_int;
String string_double = ""+liczba_double;

W prosty i szybki sposób dokonaliśmy konwersji dwóch typów liczbowych na zmienne tekstowe.

Klasa StringBuffer

Klasa StringBuffer, jest rozszerzeniem tradycyjnej klasy String. W odróżnieniu do pierwowzoru, StringBuffer może się rozszerzać i zmieniać swoją zawartość. Oznacza to, że może wstawiać znaki i podciągi w dowolnym miejscu tekstu. Kiedy wykonujemy jakieś operacje na tekście, klasa automatycznie się rozszerza. Przykład kodu klasy StringBuffer:

StringBuffer tekstBuforowany = new StringBuffer("Ala ");
System.out.println(tekstBuforowany);
System.out.println(tekstBuforowany.length());
tekstBuforowany.append("kota");
tekstBuforowany.insert(4, "ma ");
tekstBuforowany.delete(4, 7);
System.out.println(tekstBuforowany.substring(0,3));

Zinterpretujmy teraz powyższy kod:
- W linii 1 tworzymy nowy obiekt typu StringBuffer.
- W linii 2 wyświetlamy zawartość tego obiektu.
- W linii 3 wyświetlamy długość tekstu będącego w obiekcie tekstBuforowany.
- W linii 4 dodajemy na koniec tekstu słowo kota.
- W linii 5 wstawiamy w środek tekstu słowo ma .
- W linii 6 usuwamy wstawione przed chwilą słowo.
- W linii 7 wyświetlamy słowo Ala.

Oczywiście w powyższym przykładzie przedstawiłem tylko kilka kluczowych metod klasy StringBuffer. Zachęcam Was, drodzy czytelnicy do analizy dokumentacji i zapoznania się z pozostałymi metodami, tej niezwykle użytecznej klasy.

Klasa StringBuilder

Wersja Javy J2SE 5, dodaje nową klasę mianowicie: StringBuilder. Funkcjonalnością bardzo przypomina opisaną wyżej klasę StringBuffer. Zasadniczą różnicą jest brak obsługi synchronizacji w tej klasie. Brak synchronizacji, uniemożliwia tworzenie bezpiecznych aplikacji wielowątkowych, ale w znaczący sposób zwiększa wydajność. Dlatego w wypadku prostych aplikacji, lepiej posłużyć się właśnie tą klasą.

Klasa StringTokenizer

Klasa StringTokenizer swoim działaniem przypomina działanie funkcji split. Dzieli ona wejściowy łańcuch, według określonego separatora. StringTokenizer posiada jednak olbrzymią zaletę w stosunku do funkcji split. Pozwala robić z uzyskanymi fragmentami łańcuchów co tylko chcemy. Możemy np. przypisać je do zmiennych, wypełnić nimi tablicę, a nawet kilka tablic. Klasa StringTokenizer często używana jest do odczytu specyficznych danych o stałej strukturze np. w plikach CSV. W ten sposób odczytujemy każdy rekord i operujemy danymi z poszczególnych jego fragmentów. Przykład:

String dane = "tekst1=aaa;" +
"tekst2=bbb;" +
"tekst3=ccc;";
// Tworzymy obiekt StringTokenizer
StringTokenizer stringTokenizer = new StringTokenizer(dane, "=;");
while(stringTokenizer.hasMoreTokens())
{
	String klucz = stringTokenizer.nextToken();
	String wartosc = stringTokenizer.nextToken();
	System.out.println(klucz + " = " + wartosc);
}

Prześledźmy powyższy kod. Najpierw tworzymy trzyliniowy String, w którym używamy dwóch separatorów = i ;. Przed znakiem równości znajduje się klucz, po nim jego wartość. Znak średnika oznacza koniec jednego rekordu. W linii 5 tworzymy obiekt klasy StringTokenizer, w którym deklarujemy zdefiniowany przed chwilą łańcuch dane oraz podajemy separatory zdefiniowane powyżej. Następnie w pętli while (która jest prawdziwa dopóki w Stringu znajdują się kolejne linie - metoda hasMoreTokens()), odczytujemy klucz i wartość a następnie wyświetlamy je na ekranie użytkownika.

Klasa StringTokenizer jest niewątpliwie użyteczną klasą, zwłaszcza przy przetwarzaniu danych, które mają regularny charakter.

Data ostatniej modyfikacji: 30.07.2013, 22:51.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus