Символы char
Метод charAt возвращает не строку, а один символ — значение типа char. В этом уроке разберём, что лежит внутри такого значения и почему символы иногда складываются как числа.
Вернёмся к карточке. В каждой её клетке видна буква, но компьютер хранит не буквы, а числа. У каждого символа есть номер в общей таблице символов Юникод: у a это 97, у b — 98, у A — 65. Клетка карточки на самом деле хранит этот номер, а println при печати превращает его обратно в букву:
public class Main {
public static void main(String[] args) {
char c = 'a';
System.out.println(c); // a
System.out.println((int) c); // 97
System.out.println(c + 1); // 98
System.out.println((char) (c + 1)); // b
}
}Давайте разберём программу по строкам:
char c = 'a';кладёт вcсимволa, а внутри — его номер 97.println(c)печатает символ:printlnвидит, что перед нимchar.(int) cприводит символ кintи показывает номер —97.c + 1— уже арифметика: результат имеет типint, и печатается98.(char) (c + 1)приводит число98обратно кchar, и печатаетсяb.
char — это число
Код символа — его номер в таблице Юникод. Значение char — 16-битное число без знака, от 0 до 65535, и хранит оно именно код. Поэтому с char работает арифметика:
- в выражении с
intили с другимcharсимвол превращается вint, и результат тожеint; - чтобы получить символ обратно, нужно приведение
(char); - коды латинских букв и цифр идут подряд:
'a'— 97,'b'— 98,'A'— 65,'0'— 48.
char и String в одном выражении
Вспомните правило склейки: если с одной стороны от + стоит строка, + склеивает. Если строки нет, + складывает числа, а char — это число:
String name = "Bob";
char first = name.charAt(0);
System.out.println(first == 'B'); // true
System.out.println(first + 1); // 67
System.out.println("" + first + 1); // B1first == 'B'даётtrue.char— примитивный тип, поэтому==сравнивает сами значения, а не ссылки, как у строк.first + 1складывает кодB, 66, с единицей и печатает67.- В
"" + first + 1слева пустая строка, поэтому оба+склеивают, и печатаетсяB1.
На собеседовании любят спросить, что напечатает сумма двух символов в println. Ответ даёт то же правило: строки нет — значит, складываются коды.
Здесь картинка с карточкой неточна. Кажется, что любой символ занимает ровно одну клетку. Но 16 бит хватает не на всё: многие эмодзи занимают в строке по две клетки-char, и "😀".length() даёт 2.
Проверки символов
Для проверок символов есть класс Character с готовыми методами:
Character.isDigit(c)— цифра ли это;Character.isLetter(c)— буква ли это;Character.toUpperCase(c)— та же буква, но заглавная.
Это static-методы: их вызывают через имя класса, и import для них не нужен. Вот подсчёт цифр в строке:
String code = "A7-42b";
int digits = 0;
for (int i = 0; i < code.length(); i++) {
if (Character.isDigit(code.charAt(i))) {
digits++;
}
}
System.out.println(digits); // 3Цикл проходит по индексам от 0 до length() - 1. charAt(i) достаёт очередной символ, а Character.isDigit проверяет, цифра ли он. Цифр в строке три: 7, 4 и 2.
Частая ошибка
Инициалы собрали из двух charAt через +:
String first = "Anna";
String last = "Lee";
System.out.println(first.charAt(0) + last.charAt(0)); // ✗Хотели напечатать AL, а программа печатает 141. charAt возвращает char, строки в выражении нет, и + складывает коды 65 и 76. Поставьте слева пустую строку: "" + first.charAt(0) + last.charAt(0) печатает AL.
Главное
charхранит код символа — 16-битное число;(int) cпоказывает код, а(char)превращает код в символ.- Арифметика с
charиintдаётint:'a' + 1— это98, и дваcharчерез+складываются как числа. - Чтобы склеить символы, слева нужна строка:
"" + c1 + c2. charAtвозвращаетchar, а классCharacterпроверяет символы:isDigit,isLetter.