Formatowanie łańcuchów znaków
Na pewno kilka razy zastanawiałeś się, dlaczego nie można w prosty sposób formatować Stringi. Okazuje się, że w formatowanie łańcuchów znaków Javie jest to bardzo proste. Poniżej zaimplementowałem pomocniczą klasę Cat, przechowującą model danych (w tym przypadku są to 'właściwości’ kota).
public class Cat { private String name; private String race; private int age; private double value; private char sex; public Cat(String name, String race, int age, double value, char sex) { this.name = name; this.race = race; this.age = age; this.value = value; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRace() { return race; } public void setRace(String race) { this.race = race; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public double getValue() { return value; } public void setValue(double value) { this.value = value; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } }
public class StringFormatSample { public static void main(String[] args) { Cat cat = new Cat("Emma", "Persian", 10, 100.5, 'F'); String sampleText = String.format("The name of my cat is %s and it race is %s. It sex is %c and it is %d years old. \nI bought him for the price %f", cat.getName(), cat.getRace(), cat.getSex(), cat.getAge(), cat.getValue()); System.out.println(sampleText); } }
Metoda format
Zasada tworzenia sformatowanego tekstu jest prosta. Używasz statycznej metody z klasy String o nazwie 'format’. W nawiasie wpisujesz jakiś napis, który zawiera specjalne aliasy, symbolizujące rodzaj danych, które chcesz wyświetlisz. Dane te w postaci zmiennych (typu String, int, double, itp.) wypisujesz po przecinku. Jest to o tyle pożyteczne, że jeśli się pomylisz i chciałbyś zawsze wyświetlać liczbę całkowitą (np. w przypadku wieku), a w obiekcie Cat pod zmienną age będzie coś innego, to czeka Cię taki komunikat na konsoli:
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.Double at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302) at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2793) at java.util.Formatter$FormatSpecifier.print(Formatter.java:2747) at java.util.Formatter.format(Formatter.java:2520) at java.util.Formatter.format(Formatter.java:2455) at java.lang.String.format(String.java:2940) at basics.lesson17.StringFormatSample.main(StringFormatSample.java:8)
W następnej klasie piszę metodę main, aby przetestować mój formater. Tworzę obiekt klasy Cat, wypełniając go przykładowymi danymi oraz formatuję tekst za pomocą metody String.format.
public class DateFormatSample { public static void main(String[] args) { Calendar birthDay = new GregorianCalendar(1988, 7, 1); String sampleFormatString = String.format("My birthday: %1$td - %1$tm - %1$tY", birthDay); System.out.println(sampleFormatString ); SimpleDateFormat dateFormatter = new SimpleDateFormat("E, y-M-d 'at' h:m:s a z"); Date now = new Date(); System.out.println("Format: " + dateFormatter.format(now)); } }
Czasami możesz znaleźć formatowanie łańcuchów znaków, używając specyfikatora formatu pisanego wielką literą (np. zamiast %s, będzie %S). Różnica między między pierwotnym podejściem, a tym, które opisałem w poprzednim zdaniu, polega na tym, że Twój tekst będzie przeformatowany na wielkie litery.
Czyli zapis: String.format(„%S”, „Hi James!”); jest równoważny z: String.format(„%s”, „Hi James!”).toUpperCase();
Tabelka ułatwiająca formatowanie łańcuchów znaków:
Specyfikator formatu | Typ danych wejściowych | Wynik |
%s | każdy | łańcuch znaków (String) |
%f | typ zmiennoprzecinkowy (float) | liczba ułamkowa w notacji dziesiętnej |
%c | typ znakowy (char) | typ znakowy zgodny z kodowaniem Unicode |
%d | typy całkowite (incl. byte, short, int, long, bigint) | liczba całkowita w notacji dziesiętnej |
Formatowanie łańcuchów znaków można alternatywnie wykonać za pomocą klasy StringUtils z zewnętrznej biblioteki commons-lang*.
* https://commons.apache.org/proper/commons-lang/
Link do lekcji: https://github.com/developeronthego/java-basics/tree/main/src/main/java/basics/lesson17
Lekcja o klasie String: https://developeronthego.pl/java-podstawy-8-string-stringbuilder-stringbuffer/