1. Problem ręcznej konkatenacji
Jeśli trzeba wypisać jedną–dwie zmienne, operator + jest naprawdę wygodny. Ale gdy danych jest dużo, konkatenacja szybko zamienia się w chaos, zwłaszcza gdy potrzebne jest formatowanie liczb (np. 2 miejsca po przecinku) lub podziały wierszy.
String name = "Oleg";
int age = 25;
double balance = 12345.67;
System.out.println("Imię: " + name + ", wiek: " + age + ", saldo: " + balance + " euro.");
Próba „dokręcenia” formatowania wewnątrz konkatenacji tylko pogarsza czytelność:
System.out.println("Imię: " + name + ", wiek: " + age + ", saldo: " + String.format("%.2f", balance) + " euro.");
Wniosek: prosta konkatenacja jest dobra do drobiazgów, lecz do złożonych komunikatów potrzebne jest potężniejsze narzędzie — String.format().
2. String.format — formatujemy ciągi na poważnie
Metoda String.format() pozwala tworzyć łańcuch według szablonu i podstawiać wartości w określone miejsca.
Ogólna postać:
String result = String.format("Szablon", values);
- %s — napis
- %d — liczba całkowita
- %f — liczba zmiennoprzecinkowa
- %n — nowa linia (wieloplatformowo)
String name = "Oleg";
int age = 25;
double balance = 12345.6789;
String info = String.format("Imię: %s, wiek: %d, saldo: %.2f euro.", name, age, balance);
System.out.println(info);
// Wypisze: Imię: Oleg, wiek: 25, saldo: 12345.68 euro.
String result = String.format("Imię: %s, wiek: %d, saldo: %.2f euro", name, age, balance);
// %s — napis, %d — liczba całkowita, %.2f — liczba z 2 miejscami po przecinku
Formatowanie liczb i ciągów
Liczby zmiennoprzecinkowe o stałej precyzji:
double price = 99.999;
System.out.println(String.format("Cena: %.2f euro.", price)); // Cena: 100.00 euro.
Szerokość pola i wyrównanie:
int n = 7;
System.out.println(String.format("Liczba: [%5d]", n)); // Liczba: [ 7]
System.out.println(String.format("Liczba: [%-5d]", n)); // Liczba: [7 ]
[5d] — szerokość pola 5, domyślnie wyrównanie do prawej;
[-5d] — szerokość pola 5, wyrównanie do lewej.
Ciągi znaków z wyrównaniem:
String text = "Java";
System.out.println(String.format("[%10s]", text)); // [ Java]
System.out.println(String.format("[%-10s]", text)); // [Java ]
Procenty:
double percent = 0.125;
System.out.println(String.format("Gotowe: %.1f%%", percent * 100)); // Gotowe: 12.5%
Aby wypisać znak procenta, użyj %%.
Formatowanie dat (krótko)
import java.util.Date;
Date now = new Date();
System.out.println(String.format("Dzisiaj: %tD", now)); // Dzisiaj: 06/18/24
System.out.println(String.format("Czas: %tT", now)); // Czas: 15:42:07
Lokalizacja i separatory
Domyślnie używana jest lokalizacja systemu. Aby ustawić własną (np. przecinek jako separator części ułamkowej), przekaż lokalizację — na przykład Locale.FRANCE.
import java.util.Locale;
double price = 1234.56;
System.out.println(String.format(Locale.FRANCE, "%.2f", price)); // 1234,56
Praktyczne przykłady
Przykład 1: Krótki raport
String name = "Anna";
int tasks = 5;
double hours = 12.3456;
String report = String.format(
"Pracownik: %s%nWykonanych zadań: %d%nPoświęcono godzin: %.1f",
name, tasks, hours
);
System.out.println(report);
/* Wypis:
Pracownik: Anna
Wykonanych zadań: 5
Poświęcono godzin: 12.3
*/
Przykład 2: Tabela z wyrównaniem
String header = String.format("%-10s | %5s | %8s", "Imię", "Punkty", "Czas");
String row1 = String.format("%-10s | %5d | %8.2f", "Oleg", 95, 10.5);
String row2 = String.format("%-10s | %5d | %8.2f", "Anna", 100, 9.75);
System.out.println(header);
System.out.println(row1);
System.out.println(row2);
/* Wypis:
Imię | Punkty | Czas
Oleg | 95 | 10.50
Anna | 100 | 9.75
*/
Przykład 3: Mieszany tekst
int apples = 12;
int pears = 8;
System.out.println(String.format("Mam %d jabłek i %d gruszek.", apples, pears));
3. Praktyka: formatowanie ciągów w naszej aplikacji
Dodajmy formatowanie do aplikacji konsolowej: saldo zawsze z dwoma miejscami po przecinku, nowe linie — przez %n.
Scanner console = new Scanner(System.in);
System.out.print("Wpisz imię: ");
String name = console.nextLine();
System.out.print("Wpisz wiek: ");
int age = console.nextInt();
System.out.print("Wpisz saldo: ");
double balance = console.nextDouble();
// Sformatowane wyjście
String info = String.format("Imię: %s, wiek: %d, saldo: %.2f euro.", name, age, balance);
System.out.println(info);
Spróbuj:
- Wprowadzać różne wartości i sprawdzić, że saldo zawsze jest wypisywane z dwoma miejscami po przecinku (%.2f).
- Zmienić szablon, aby dodać podziały wierszy za pomocą %n.
4. Typowe błędy przy formatowaniu ciągów
Błąd nr 1: Niezgodność typów i znaczników.
Nie można podstawiać napisu do %d ani liczby do %s.
String.format("Wiek: %d", "dwadzieścia"); // Błąd: oczekiwano liczby, przekazano napis
Błąd nr 2: Pomylenie kolejności argumentów.
Wzorzec %s %d, a najpierw przekazano liczbę, potem napis — otrzymasz błąd lub nieprawidłowy wynik.
Błąd nr 3: Ignorowanie ustawień regionalnych.
Spodziewałeś się przecinka jako separatora części ułamkowej, a widzisz kropkę — ustaw odpowiednią lokalizację jawnie jako pierwszy parametr String.format(...).
Błąd nr 4: Nieucieczony znak procenta.
Aby wypisać znak %, użyj %%, w przeciwnym razie formatowanie zakończy się błędem.
GO TO FULL VERSION