Typy i operacje tekstowe

Podstawowy typ tekstowy w języku Java to klasa java.lang.String. Klasa String reprezentuje niemodyfikowalną sekwencję znaków.

Z jednej strony klasa String to klasa jak każda inna, a z drugiej, jest to typ absolutnie kluczowy, którego używamy w sposób często wyjątkowy. Zacznijmy od tego, że w sposób absolutnie wyjątkowy tworzymy instancje tej klasy.

Aby utworzyć obiekt typu String nie posługujemy się standardowym operatorem new, tylko literałami, zupełnie jak w przypadku typów prostych (prymitywnych). Aby więc utworzyć obiekt typu String reprezentujący napis „Witaj świecie!” napiszemy:

String helloWorld = "Witaj świecie!";

Klasa String udostępnia szereg metod umożliwiających wykonywanie prostych operacji tekstowych, takich jak np. zamienianie wielkich liter na małe czy zastępowanie określonych znaków innymi. Pełna lista dostępnych metod wraz z opisami znajduje się w dokumentacji klasy String, jednak zanim zabierzemy się do lektury tejże zapoznajmy się z prostym, ale niezmiernie ważnych faktem – obiekty klasy String są niemodyfikowalne.

Co to oznacza, że obiekty klasy String są niemodyfikowalne? W jaki sposób zatem metoda toLowerCase() może zmienić wielkie litery na małe (bo właśnie to ona robi)? Otóż metoda ta, podobnie jak wszystkie inne metody klasy String nie tyle zmienia istniejący obiekt, co tworzy nowy obiekt, który jest wynikiem wykonanej operacji. Dotychczas istniejący obiekt pozostaje bez zmian. Zerknijmy na poniższy program:

public class TestClass {
  public static void main(String[] args) {
    String strA = "AbCdE";
  
    String strB = strA.toLowerCase();
  
    System.out.println(strA);
    System.out.println(strB);
  }
}

W pierwszej linii programu tworzymy referencję strA typu String oraz obiekt typu String reprezentujący napis „AbCdE” i przypisujemy ten obiekt do referencji.

W drugiej linii uruchamiamy dla obiektu wskazywanego przez referencję strA metodę toLowerCase(). Metoda ta zamienia wszystkie wielkie litery na małe, jednak nie w ten sposób, że modyfikuje istniejący obiekt, bo to jest niemożliwe. Wywołanie metody toLowerCase() powoduje utworzenie nowego obiektu typu String, który to obiekt reprezentuje napis „abcde”. Obiekt ten jest zwracany jako wynik działania metody i przypisujemy go do referencji strB. O tym, że oryginalny obiekt, na który wskazuje referencja strA się nie zmienił, możemy przekonać się wyświetlając jego wartość na ekranie. Uruchommy ten program i przekonajmy się, że rezultatem jego działania będzie wyświetlenie napisów „AbCdE” oraz „abcde”.

W analogiczny do przedstawionego powyżej sposób działają wszystkie metody klasy String. Ponieważ obiektów klasy String nie da się zmienić, zatem operacje te zwracają nowe obiekty, przekształcone zgodnie z algorytmem uruchomionej metody.

Klasa String jest z jednej strony klasą jak każda inna, w związku z czym możemy dla jej instancji wywoływać metody tak jak dla instancji każdej innej klasy, jednak jednocześnie jest klasą bardzo specjalną.

Oprócz tego, że instancje klasy String tworzymy w sposób niestandardowy, to możemy też w sposób niestandardowy wykonywać dla instancji tej klasy pewną często wykonywaną operację, a mianowicie operację konkatenacji. Aby skleić (skonkatenować) dwa teksty możemy – posługując się operacją String concat(String str) – napisać:

public class TestClass {
  public static void main(String[] args) {
    String strA = "AbCdE";
  
    String strB = strA.concat("fGhI");
  
    System.out.println(strA);
    System.out.println(strB);
  }
}

Ale możemy także skorzystać ze wspomnianej już wyjątkowości, i użyć operatora +, zupełnie tak jakbyśmy napisy do siebie dodawali. Możemy więc zamiast powyższego napisać:

public class TestClass {
  public static void main(String[] args) {
    String strA = "AbCdE";
  
    String strB = strA + "fGhI";
  
    System.out.println(strA);
    System.out.println(strB);
  }
}

Wiemy już, że metoda concat(…) nie zmienia obiektu wskazywanego przez referencję strA tylko tworzy nowy obiekt – obiekt który reprezentuje sklejone napisy. Dokładnie to samo robi operator +. Nie ma żadnych wyjątków od reguły, że obiekty typu String są niemodyfikowalne.

Skoro każdorazowe użycie operatora + czy operacji concat(…) powoduje utworzenie nowego obiektu, to wielokrotne wykonywanie tych operacji (np. w pętli) musi być (i jest) dość kosztowne. Z tego powodu nie powinniśmy w takim przypadku używać klasy String, tylko innej klasy, istniejącej właśnie po to, by łańcuchy znaków budować. Klasa String służy zasadniczo do reprezentowania łańcuchów, natomiast do budowanie tekstów służy klasa java.lang.StringBuilder.

Przykładowo, poniższy program buduje tekst zawierający kolejne liczby dwucyfrowe podzielne przez liczbę przekazaną jako argument wywołania:

String dividables(int div) {
  StringBuilder strBuilder = new StringBuilder();
  
  for (int x = 10; x < 100; x++)
    if (x % div == 0)
      strBuilder.append(x).append(" ");
  
  return strBuilder.toString().trim();
}

W pętli FOR powyższego programu iterujemy po kolejnych liczbach z przedziału od 10 do 99 i jeśli dana liczba jest podzielna przez liczbę przekazaną jako argument wywołania to doklejamy ją za pomocą operacji append(…).

Operacja append(…) klasy StringBuilder dokleja (konkatenuje) przekazany argument do końca tekstu, bez tworzenia nowych obiektów i innych zbędnych operacji.

Po doklejeniu liczby doklejamy jeszcze spację, aby oddzielić od siebie poszczególne wartości. Na koniec używamy metody toString() aby przekonwertować obiekt klasy StringBuilder na obiekt klasy String. Używamy jeszcze metody trim() z klasy String aby pozbyć się spacji doklejonej za ostatnią liczbą. Oczywiście wywołanie metody trim() spowoduje utworzenie dodatkowej instancji klasy String, ale jest to operacja wykonywana jednokrotnie, więc nie mamy się czym martwić. Co dokładnie robi metoda trim()? Odszukajmy w ramach ćwiczenia opis we wspomnianej na początku dokumentacji klasy.

4
Dodaj komentarz

avatar
4 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Doradca GSM Recent comment authors
  Subscribe  
najnowszy najstarszy oceniany
Powiadom o