Formatowanie i składanie tekstu
- Teksty i String
- poziom: początkujący
- aktualizacja: 16 sierpnia 2026
Łączenie kilku napisów operatorem + jest czytelne, ale w pętli tworzy stos obiektów pośrednich, z których każdy od razu ląduje na śmietniku. Do raportów i tabel lepiej pasuje StringBuilder, a układ kolumn najłatwiej kontrolować przez String.format. Od Javy 15 wielowierszowy HTML albo SQL zapiszesz jako blok tekstu """ — bez ręcznego dopisywania \n i bez poprzedzania każdego cudzysłowu ukośnikiem.
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Locale;
/**
* String.format, StringBuilder i bloki tekstu — skryptyJAVA.pl
* Zapisz jako: FormatowanieTekstu.java
*/
public final class FormatowanieTekstu {
private static final Locale POLSKI = Locale.forLanguageTag("pl-PL");
/** Prosty, niezmienny wiersz danych do raportu. */
public record Produkt(String nazwa, int ilosc, BigDecimal cena) {}
private FormatowanieTekstu() {
// Klasa narzędziowa nie wymaga obiektów.
}
/** Formatuje liczby zgodnie z polskim locale: grupowanie tysięcy i przecinek dziesiętny. */
public static String etykieta(Produkt produkt) {
return String.format(POLSKI, "%s — %,d szt. po %,.2f zł",
produkt.nazwa(), produkt.ilosc(), produkt.cena());
}
/** Buduje tabelę bez tworzenia nowego pełnego napisu przy każdym obrocie pętli. */
public static String tabela(List<Produkt> produkty) {
StringBuilder wynik = new StringBuilder();
wynik.append(String.format(POLSKI, "%-22s %8s %13s%n", "Produkt", "Ilość", "Wartość"));
wynik.append("-".repeat(45)).append(System.lineSeparator());
BigDecimal suma = BigDecimal.ZERO;
for (Produkt produkt : produkty) {
// Zaokrąglamy przed dodaniem, żeby stopka zgadzała się z sumą wydrukowanych wierszy.
BigDecimal wartosc = produkt.cena()
.multiply(BigDecimal.valueOf(produkt.ilosc()))
.setScale(2, RoundingMode.HALF_UP);
suma = suma.add(wartosc);
wynik.append(String.format(POLSKI, "%-22s %8d %10.2f zł%n",
skroc(produkt.nazwa(), 22), produkt.ilosc(), wartosc));
}
wynik.append("-".repeat(45)).append(System.lineSeparator());
wynik.append(String.format(POLSKI, "%-31s %10.2f zł%n", "Razem:", suma));
return wynik.toString();
}
/**
* Skraca tekst do zadanej liczby znaków i dopisuje wielokropek, zamiast uciąć po cichu.
* Liczy punkty kodowe: nie rozrywa par zastępczych, ale może przeciąć flagę lub emoji ZWJ.
*/
public static String skroc(String tekst, int limit) {
if (limit < 1) {
return "";
}
if (tekst.codePointCount(0, tekst.length()) <= limit) {
return tekst;
}
return tekst.substring(0, tekst.offsetByCodePoints(0, limit - 1)) + "…";
}
/**
* Wstawia dane do czytelnego bloku tekstu; treść jest wcześniej kodowana dla HTML-a.
* Oba argumenty muszą być różne od null.
*/
public static String stronaHtml(String tytul, String tresc) {
String szablon = """
<!doctype html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>%s</title>
</head>
<body>
<h1>%s</h1>
<p>%s</p>
</body>
</html>
""";
String bezpiecznyTytul = kodujHtml(tytul);
return szablon.formatted(bezpiecznyTytul, bezpiecznyTytul, kodujHtml(tresc));
}
/**
* Minimalne kodowanie tekstu umieszczanego między znacznikami HTML.
* Argument nie może być null — metoda nie sprawdza go i rzuci NullPointerException.
*/
public static String kodujHtml(String tekst) {
return tekst.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """)
.replace("'", "'");
}
// ── PRZYKŁADY ───────────────────────────────────────────
public static void main(String[] args) {
List<Produkt> produkty = List.of(
new Produkt("Kawa ziarnista", 2, new BigDecimal("39.90")),
new Produkt("Kubek programisty", 12, new BigDecimal("24.50")),
new Produkt("Zestaw kubków termicznych premium", 3, new BigDecimal("19.99")),
new Produkt("Książka o Javie", 1_250, new BigDecimal("79.99")));
System.out.println(etykieta(produkty.get(3)));
System.out.println();
System.out.print(tabela(produkty));
System.out.println();
System.out.println(stronaHtml("Java & tekst", "Bezpieczne <formatowanie>"));
}
}
Jak użyć tego skryptu
- Zapisz kod jako
FormatowanieTekstu.java(nazwa pliku musi zgadzać się z nazwą klasy publicznej) i uruchom przezjava FormatowanieTekstu.java. Program wypisze polsko sformatowaną etykietę, tabelę produktów i gotowy dokument HTML. - Do pojedynczego komunikatu użyj
String.format(locale, wzorzec, argumenty)albo krótszegowzorzec.formatted(argumenty). Znaczniki%s,%di%.2foznaczają napis, liczbę całkowitą i liczbę z dwoma miejscami. - Gdy składasz tekst w pętli, utwórz jeden
StringBuilder, dopisuj fragmenty metodąappend, a na końcu pobierz wynik przeztoString(). Metodatabelapokazuje pełny wzorzec — razem zskroc, bo sama precyzja we wzorcu (np.%-22.22s) ucina za długą nazwę bez śladu i może rozdzielić parę zastępczą.skrocchroni pojedyncze punkty kodowe, lecz nie całe klastry grafemowe, np. flagi i rodzinne emoji ZWJ. - Wielowierszowy szablon umieść między
""", a pola wstaw przezformatted. Jeśli dane pochodzą od użytkownika, zakoduj je odpowiednio dla miejsca docelowego — w przykładzie robi tokodujHtml.
Warto wiedzieć
- Zawsze podawaj
Locale, gdy wynik ma trafić do użytkownika albo do pliku o ustalonym formacie. Bez niego ten sam kod wypisze1,234.50na Twoim laptopie i1 234,50na serwerze produkcyjnym. I uważaj na to drugie: separatorem tysięcy w polskim locale jest twarda spacjaU+00A0, a nie zwykła. Napisu „1 250 000” z%,dnie oczyścisz przezreplace(" ", "")ani nie sparsujesz wprost z powrotem na liczbę. Do danych maszynowych — CSV, JSON, kolumna liczbowa w bazie — formatuj bez przecinka we wzorcu, czyli samym%d. - W formaterze
%noznacza separator linii właściwy dla systemu, natomiast\nzawsze pojedynczy znak LF. Do tekstu wyświetlanego w terminalu zwykle wybieraj%nlubSystem.lineSeparator(). StringBuildernie jest bezpieczny wątkowo, ale lokalna zmienna w metodzie nie jest współdzielona i właśnie tak należy go zwykle używać. Nie zastępuj go wolniejszymStringBufferbez konkretnej potrzeby synchronizacji.- Kodowanie HTML zależy od kontekstu. Metoda z przykładu nadaje się do zwykłego tekstu między znacznikami, lecz nie zastępuje kodowania adresów URL, JavaScriptu ani wartości CSS. Do rozbudowanych stron użyj silnika szablonów z automatycznym escapingiem.
Podobne skrypty
Walidacja danych: e-mail, PESEL i NIP
Zestaw gotowych metod sprawdzających adres e-mail, numer PESEL (data urodzenia, płeć i cyfra kontrolna) oraz NIP z sumą kontrolną modulo 11, z tolerancją myślników i spacji.
średni Zobacz kod → Teksty i StringPrzyjazny URL z polskich znaków
Zamienia tytuł „Żółć i Łódź!” na adres zolc-i-lodz: polskie litery rozkłada Normalizer, znaki specjalne wypadają, powtórzone separatory sklejają się w jeden, a duplikat nazwy dostaje kolejny numer.
średni Zobacz kod → Teksty i StringSortowanie polskich napisów (Collator)
Sortowanie i porównywanie tekstów tak, jak układa je polski alfabet: Collator zamiast String.compareTo, opcjonalne rozróżnianie wielkości liter, bezpieczna obsługa null i sortowanie rekordów po nazwisku.
średni Zobacz kod →