Cześć wszystkim! Często nasze metody zawierają liczby, które należy wyświetlić w specjalnym formacie. Wydaje się, że to drobnostka, ale jak zrealizowałbyś to zadanie? Zachęcamy Cię dzisiaj do chwili zastanowienia się nad tym. Na początek, aby zagłębić się w formatowanie liczb w Javie, pamiętajmy o metodzie formatowania klasy String : public static String format(Format String, Obiekt... args) - zwraca ciąg znaków sformatowany z ciągu formatującego przy użyciu pozostałych argumentów args . I tylko przykład:
Użyjmy bardziej odpowiedniego formatu dla double :
To jest skrócona lista możliwych flag formatowania daty - jest ich wiele, na każdy gust. Pełną ich listę wraz z możliwymi specyfikatorami można znaleźć pod tym linkiem . Przyjrzyjmy się, jak z tego skorzystać. Tym razem nie używamy String.format() , ale od razu System.out.printf() .
String str = String.format("Cześć - %s! Jak się masz %s?", „Sasza”, "W pracy");
System.out.println(str);
W rezultacie otrzymamy wynik w konsoli:
Witaj Sasza! Jak sprawy w pracy?
Metody printf i format
String.format() nie jest jedyną metodą formatowania ciągu. Jego odpowiednikami są System.out.printf() i System.out.format(); . Możemy więc zastąpić poprzedni kod:System.out.printf("Cześć - %s! Jak się masz %s?", „Sasza”, "W pracy");
Lub
System.out.format("Cześć - %s! Jak się masz %s?", „Sasza”, "W pracy");
Dane wyjściowe w konsoli pozostaną takie same. Jedyna różnica polega na tym, że metody te natychmiast wyświetlają wartość w konsoli, w przeciwieństwie do String.format() . Ale bardziej podoba mi się String.format() , ponieważ nie zawsze musimy wyświetlać wynik w konsoli, więc będziemy używać tej metody dalej. Wróćmy do naszego przykładu. Co widzimy? A faktem jest, że w miejscach, w których znajdowały się znaki - %s , wstawiane są linie - „Sasha” i „w pracy” . Jak może nam to pomóc w rozwoju? Wyobraź sobie, że masz duży tekst szablonu, ale w niektórych miejscach musisz wstawić wartości, które mogą się różnić i pochodzić jako argumenty z zewnątrz. Tutaj właśnie przydaje się to formatowanie. Specyfikatory formatu zaczynają się od znaku procentu, % i kończą znakiem wskazującym typ argumentu, który ma zostać sformatowany. I, jak zapewne rozumiesz, %s służy do wstawiania obiektów - ciągów znaków. Ale jeśli spróbujemy wstawić np. double w miejscu rejestracji obiektu string:
String str = String.format("Cześć - %s! Jak się masz %s?", 55.6, "W pracy");
to również zadziała. double zostanie rzutowane na ciąg znaków i otrzymamy:
Witam - 55,6! Jak sprawy w pracy?
Oprócz łańcuchów i liczb zmiennoprzecinkowych w Javie są jeszcze inne typy, prawda? Przyjrzyjmy się więc całemu arsenałowi:
Typ wartości do sformatowania | Przykład | |
---|---|---|
%S | Dowolny typ, który zostanie rzutowany na ciąg |
Wynik:
Witaj świecie!
|
%B | Dowolny typ, który zostanie rzutowany na wartość logiczną : true – jeśli wartość nie jest null, false – jeśli null |
Wynik:
Witam, fałsz
|
%H | Możesz przekazać dowolny obiekt, który zostanie rzutowany na ciąg wartości szesnastkowych z metody hashCode() |
Wynik:
Witaj 106c44!
|
%C | Służy do określania znaku Unicode ( char ) |
Wynik:
Witaj świecie!
|
%D | Określono liczbę całkowitą ( int. byte, short, int, long, BigInteger ) |
Wynik:
Mam już 20 lat!
|
%F | Służy do określania liczby zmiennoprzecinkowej |
Wynik:
Numer PI to - 3,141590!
|
%mi | Liczby zmiennoprzecinkowe w notacji naukowej |
Wynik:
Numer PI to - 3,141590e+00!
|
%A | Liczby zmiennoprzecinkowe będą reprezentowane w formacie szesnastkowym |
Wynik:
Numer PI to - 0x1.921f9f01b866ep1!
|
%X | Przekazana jest liczba całkowita ( int. byte, short, int, long, BigInteger ), wynikiem formatowania będzie znak o podanej liczbie w tabeli ASCII |
Wynik:
Mam już 19 lat!
|
% o | Liczba całkowita ( int. byte, short, int, long, BigInteger ) jest akceptowana i będzie reprezentowana jako liczba ósemkowa |
Wynik:
Mam już 31 lat!
|
%T | Prefiks konwersji daty i godziny. Do formatowania wymagane są dodatkowe flagi |
Wynik:
Dzisiaj jest sobota
|
%N | Separator linii specyficzny dla platformy. Analogowy\n |
Wynik:
cześć cześć
|
String str = String.format(„Odległość z Kijowa do Odessy wynosi %f. Nie taka mała, prawda?”, 475.4d);
System.out.println(str);
Wyjście konsoli:
Odległość z Kijowa do Odessy wynosi 475,400000. Nie tak mało, prawda?
Jak zapewne zauważyłeś, %f byłoby bardziej odpowiednim specyfikatorem dla liczb zmiennoprzecinkowych, które w Javie obejmują typy danych takie jak double i float . Za pomocą tego specyfikatora możemy sformatować liczbę zmiennoprzecinkową:
String str = String.format(„Odległość z Kijowa do Odessy to %.2f. Nie taka mała, prawda?”, 475.4d);
Wstawienie .2 do tego specyfikatora spowoduje obcięcie liczby miejsc po przecinku do dwóch, co da nam wynik:
Odległość z Kijowa do Odessy wynosi 475,40. Nie tak mało, prawda?
.2 nie jest jedyną poprawką w specyfikatorach. Kombinacja tych podzbiorów nazywana jest instrukcją . Ogólna forma instrukcji jest następująca:
%[argument_index][flags][width][.precision]specyfikator typu
Teraz rozszyfrujmy wszystko w kolejności:
- [indeks_argumentów] jest liczbą całkowitą wskazującą pozycję na liście argumentów. Na przykład łącze do pierwszego argumentu to 1 USD, łącze do drugiego argumentu to 2 USD itd. Jeśli pozycja nie została określona, argumenty muszą być w tej samej kolejności, w jakiej są wymienione w ciągu formatującym.
- [flagi] to znaki specjalne służące do formatowania. Na przykład:
- + flaga wskazująca, że jeśli wartość liczbowa jest dodatnia, musi zawierać znak +
- - oznacza wyrównanie wyniku do lewej strony
- , ustawia separator tysięcy dla liczb całkowitych
- [szerokość] to dodatnia dziesiętna liczba całkowita określająca minimalną liczbę znaków, które zostaną wypisane. Jeśli przed tą liczbą znajduje się 0, to brakujące znaki zostaną uzupełnione 0, jeśli nie ma 0, to spacjami.
- [.accuracy] to nieujemna liczba całkowita poprzedzona kropką. Zwykle używane do ograniczenia liczby znaków. Konkretne zachowanie zależy od konkretnego typu specyfikatora.
String str = String.format("%1$+09.5f", 3.1415926535897);
System.out.print(str);
I odpowiednio wynik w konsoli:
+03.14159
Wydaje się łatwe, prawda? Ale jeśli chodzi o formatowanie liczby, nie można zignorować DecimalFormat . Zastanówmy się, co to oznacza.
Format dziesiętny
DecimalFormat to klasa służąca do formatowania dowolnej liczby w Javie, niezależnie od tego, czy jest to liczba całkowita, czy liczba zmiennoprzecinkowa. Po utworzeniu obiektu DecimalFormat można określić szablon do formatowania liczb przychodzących bezpośrednio w konstruktorze. Tak wyglądałby nasz przykład przy użyciu DecimalFormat :DecimalFormat dF = new DecimalFormat( "#.###" );
double value = 72.224463;
System.out.print(dF.format(value));
Wyjście konsoli:
72224
Linia #.### to wzór wskazujący, że formatujemy przekazaną wartość z dokładnością do 3 miejsc po przecinku. Jakie inne symbole są dostępne dla wzorów? Tutaj jest kilka z nich:
- # — cyfra, zera wiodące są pomijane;
- 0 — cyfra jest zawsze wyświetlana, nawet jeśli liczba ma mniej cyfr (w tym przypadku wyświetla się 0);
- . — znak separatora dziesiętnego;
- , — znak grupujący separator (np. separator tysięcy);
- ; — oddziela formaty;
- - — oznacza przedrostek liczby ujemnej;
- % - mnoży przez 100 i pokazuje liczbę w procentach;
- ? — mnoży przez 1000 i podaje liczbę w ppm;
- E - Oddziela mantysę i wykładnik w notacji naukowej.
System.out.println(new DecimalFormat( "###,###.##" ).format(74554542.224463));
Wyjście konsoli:
74.554.542,22
System.out.println(new DecimalFormat( "%###.##" ).format(0.723456));
Wyjście konsoli:
%72,35
System.out.println(new DecimalFormat( "000.###" ).format(42.224463));
Wyjście konsoli:
042.224
Aby zdefiniować nowy szablon, nie jest konieczne każdorazowe tworzenie nowego obiektu DecimalFormat . Wystarczy użyć jego metod ApplyPattern i ApplyLocalizedPattern :
DecimalFormat dF = new DecimalFormat("###.###");
dF.applyPattern("000000.000");
dF.applyLocalizedPattern("#,#00.0#");
Kiedy mówimy o formatowaniu liczby zmiennoprzecinkowej, jesteśmy bardzo zainteresowani zaokrąglaniem, prawda? Zatem podczas przycinania liczby z miejscami dziesiętnymi poza określonym wzorcem funkcja DecimalFormat zaokrągla liczbę w górę, jeśli ostatnia obcięta liczba jest większa niż 5. Co się stanie, jeśli ostatnia obcięta liczba to 5? Rzeczywiście w tym przypadku liczba ta znajduje się dokładnie pośrodku najbliższych liczb całkowitych. W takim przypadku brany jest pod uwagę poprzedni numer. Jeżeli poprzednia liczba jest parzysta, wykonywane jest zaokrąglanie:
DecimalFormat dF = new DecimalFormat("##.###");
String result = dF.format(56.4595);
System.out.println((result));
Wyjście konsoli:
56 459
Jeśli jest nieparzysty, nie jest wykonywany:
DecimalFormat dF = new DecimalFormat("##.###");
String str = dF.format(56.4595);
System.out.println((str));
Wyjście konsoli:
56 459
Różnica między formatowaniem liczb zmiennoprzecinkowych za pomocą funkcji String.format() i DecimalFormat.format() polega na tym, że w pierwszym przypadku na końcu będą zera, nawet jeśli nie ma części ułamkowej. Na przykład:
String firstStr = String.format("%.4f", 9.00001273);
System.out.println((firstStr));
Wyjście konsoli:
9,0000
DecimalFormat decimalFormat = new DecimalFormat("#.####");
String secondStr = decimalFormat.format(9.00001273);
System.out.println((secondStr));
Wyjście konsoli:
9
Jak widać, formatując liczbę 9.00001273 z dokładnością do czterech miejsc po przecinku, metoda format() klasy String zwróci wartość 9.0000 , podczas gdy podobna metoda format() klasy DecimalFormat zwróci wartość 9 .
BigDecimal i BigInteger
Skoro poruszyliśmy temat zaokrąglania liczb w Javie, porozmawiajmy o tym, jak wykorzystać do takich operacji klasę BigDecimal . Ta klasa skupia się na pracy z naprawdę DUŻYMI liczbami: dla niej maksymalne wartości double i float są za małe. Ta klasa ma wiele różnych ustawień zaokrąglania zmiennoprzecinkowego, a także wiele metod operacji arytmetycznych. Ma podobną klasę, ale koncentruje się na pracy z DUŻYMI liczbami całkowitymi - BigInteger . Więcej o BigDecimal i BigInteger możesz przeczytać w tym artykule .Formatowanie daty i godziny
Powyżej wspomniano tylko, że za pomocą format() klasy String można również sformatować godzinę i datę. Cóż, przyjrzyjmy się jak to się robi. Na początek chcielibyśmy przypomnieć, że dla dat używany jest specyfikator formatu %t . Po drugie, podczas formatowania szablonu wymagane są dodatkowe flagi formatowania dla każdego specyfikatora formatu dat. Oto możliwe flagi formatowania dat:Flagi | Opis |
---|---|
%tB | Pełna nazwa miesiąca, na przykład styczeń, luty itp. |
%tb | Skrócona nazwa miesiąca, na przykład styczeń, luty itp. |
%tA | Pełna nazwa dnia tygodnia, np. niedziela, poniedziałek |
%t | Skrócona nazwa dnia tygodnia, na przykład Sun, Mon itp. |
%tY | Rok w formacie 4-cyfrowym, na przykład od 0000 do 9999 |
%ty | Rok w formacie 2-cyfrowym, na przykład od 00 do 99 |
%tm | Miesiąc jest formatowany z zerem na początku, na przykład od 01 do 12 |
%tc | Data i godzina w formacie %ta %tb %td %tT %tZ %tY, na przykład pon. 17 lutego 03:56:12 PST 2020 |
%tD | Data w formacie %tm/%td/%ty |
%td | Dzień miesiąca w formacie dwucyfrowym, na przykład od 01 do 31 |
%te | Dzień miesiąca w formacie bez początkowego 0, na przykład od 1 do 31 |
%tT | Czas w formacie 24-godzinnym, na przykład %tH:%tM:%tS |
%tH | Godzina dnia w formacie 24-godzinnym, od 00 do 23 |
%tI | Godzina w formacie 12-godzinnym, np. od 01 do 12 |
%tM | Minuty w godzinie są formatowane z zerem wiodącym, na przykład od 00 do 59 |
%tS | Sekundy na minutę składające się z dwóch cyfr, na przykład od 00 do 59 |
%tZ | Skrót strefy czasowej, taki jak PST, UTC itp. |
Przykład 1
Dodatkowo ustalimy język wyniku przekazując go jako pierwszy argument metody:Date date = new Date();
System.out.printf(Locale.ENGLISH,"%tB %te, %tY",date,date,date);
Wyjście konsoli:
11 października 2020 r
Bez określenia języka zostanie użyty język domyślny (na przykład mam rosyjski).
Przykład 2
Wyświetlmy pełniejszą datę:Date date = new Date();
System.out.printf(„%td %tB %tY z %n%tH:%tM:%tS”,date,date,date,date,date,date,date);
I wynik w konsoli:
11 października 2020 13:43:22
Przekazywanie tego samego obiektu Date jako argumentu tyle razy... Nie wygląda to zbyt dobrze, prawda? Użyjmy wewnętrznego podzbioru $ , aby określić argument, którego chcemy użyć:
System.out.printf(„%1$td %1$tB %1$tY roku %n%1$tH:%1$tM:%1$tS”,date);
Dane wyjściowe w naszej konsoli nie ulegną zmianie. Istnieją inne, równie interesujące sposoby formatowania dat. Możesz o nich przeczytać i trochę więcej o czasie i dacie w Javie w tym materiale . To wszystko na dziś, dziękujemy za uwagę!
GO TO FULL VERSION