Строки и числа: + и format
У калькулятора Java есть ещё одно правило, и касается оно оператора +. Пока с обеих сторон от него числа, он складывает. Как только с одной из сторон оказывается текст, + перестаёт считать и начинает склеивать.
Представьте, что на экране калькулятора появилась надпись. Теперь каждое нажатие + ничего не прибавляет: оно дописывает следующее значение справа, как будто вы набрали его на клавиатуре. Давайте посмотрим, как это выглядит в программе:
public class Main {
public static void main(String[] args) {
System.out.println(1 + 2 + "3"); // 33
System.out.println("1" + 2 + 3); // 123
}
}Java выполняет + слева направо, по одному:
- В первом
printlnсначала идёт1 + 2. Оба значения — числа, поэтому получается3. Затем3 + "3": справа текст, и+склеивает, выходит33. - Во втором
printlnпервым стоит текст."1" + 2даёт12, а"12" + 3даёт123. До сложения чисел дело не доходит.
Аналогия с экраном неточна в одном: на экране 3 и "3" выглядят одинаково, а для Java это разные значения. Число 3 можно складывать, а строка "3" — это текст, и складывать её Java не будет.
Склейка строк
Склейку строк называют конкатенацией. Правило одно: если с одной стороны от + стоит строка, значение с другой стороны превращается в текст и приписывается к ней. Так можно склеить строку со значением любого типа:
String name = "Anna";
System.out.println("Hi, " + name); // Hi, Anna
System.out.println("Price: " + 2.5); // Price: 2.5
System.out.println("1" + (2 + 3)); // 15Давайте разберём по порядку:
name— переменная типаString, она хранит текстAnna."Hi, " + nameсклеивает две строки."Price: " + 2.5превращает число2.5в текст и приписывает его к строке.- В
"1" + (2 + 3)скобки выполняются первыми:2 + 3даёт5, и только потом"1" + 5склеивает15.
Этот вопрос любят задавать на собеседовании: что напечатает 1 + 2 + "3", а что "1" + 2 + 3? Оба ответа следуют из одного правила: + выполняется слева направо, и после первой строки он только склеивает.
Печать по шаблону
Длинную строку из кусков и плюсов трудно читать. Удобнее String.format: он заполняет шаблон, как бланк с пропусками. На месте пропусков в шаблоне стоят метки с %, а значения для них идут следом, по порядку:
%d— целое число;%.2f— дробное число, округлённое до двух знаков после запятой;%s— строка или любое значение как текст;%n— перевод строки.
String name = "Anna";
int age = 30;
double height = 1.6789;
String line = String.format("%s is %d, %.2f m", name, age, height);
System.out.println(line); // Anna is 30, 1.68 m
System.out.printf("%s is %d%n", name, age); // Anna is 30Разберём, что здесь происходит:
String.formatберёт шаблон и три значения. Метка%sзаменяется наAnna,%dна30, а%.2fна1.68: число округлилось до двух знаков.- Результат — обычная строка. Её кладут в
lineи печатают. System.out.printfделает то же самое, но сразу печатает результат. Как иprint, он не переводит строку сам, поэтому шаблон заканчивается на%n.
Разделитель дробной части %.2f берёт из языковых настроек компьютера. С английскими настройками программа печатает 1.68, как в комментарии, а с русскими — 1,68. А + и println печатают дробь всегда с точкой.
Метка должна подходить к значению. Если передать 2.5 в метку %d, программа остановится с исключением IllegalFormatConversionException.
Частая ошибка
Сумму двух чисел приписывают к строке без скобок:
public class Main {
public static void main(String[] args) {
int apples = 2;
int pears = 3;
String text = "Fruit: " + apples + pears; // ✗
System.out.println(text); // Fruit: 23
}
}Хотели напечатать Fruit: 5, а получили Fruit: 23. Первый + склеил строку с 2, и слева от второго + уже стоит строка. Поэтому 3 приклеилась к тексту, а не прибавилась к 2. Возьмите сумму в скобки: "Fruit: " + (apples + pears) печатает Fruit: 5.
Главное
- Если с одной стороны от
+стоит строка, он склеивает, а не складывает. +выполняется слева направо:1 + 2 + "3"— это33, а"1" + 2 + 3— это123.- Чтобы сложить числа внутри строки, возьмите сумму в скобки:
"1" + (2 + 3)— это15. String.formatиprintfподставляют значения в шаблон по меткам%d,%.2fи%s, а%nпереводит строку.