Character

Java Multithreading
9 уровень , 8 лекция
Открыта

— Привет, Амиго! Это снова я. Хотела тебе рассказать еще об одном достаточно простом классе-обёртке. Сегодня речь пойдет о Character – обертка над char.

Код
class Character
{
 private final char value;

 Character(char value) 
 {
  this.value = value;
 }

 public char charValue() 
 {
  return value;
 }

 static final Character cache[] = new Character[127 + 1];

 public static Character valueOf(char c)
 {
  if (c <= 127)
   return cache[(int)c];

  return new Character(c);
 }

 public int hashCode() 
 {
  return (int)value;
 }

 public boolean equals(Object obj) 
 {
  if (obj instanceof Character) 
  {
   return value == ((Character)obj).charValue();
  }
  return false;
 }
}

В нем есть:

1) Конструктор, который принимает внутреннее значение и метод charValue, который его возвращает.

2) Метод valueOf, который возвращает новые объекты Character, но кэширует объекты со значениями от 0 до 127. Как в Integer, Short и Byte.

3) Методы hashCode() & equals – тут нас тоже ничем не удивишь.

А еще в нем есть много полезных методов (не показаны выше). Некоторые из них я тебе сейчас перечислю:

Метод Описание
boolean isDefined(char)
Является ли символ символом Unicode?
boolean isDigit(char)
Является ли символ цифрой?
boolean isISOControl(char)
Является ли символ управляющим?
boolean isLetter(char)
Является ли символ буквой?
boolean isJavaLetterOrDigit()
Является ли символ буквой или цифрой?
boolean isLowerCase(char)
Это символ в нижнем регистре (строчная буква)?
boolean isUpperCase(char)
Это символ в верхнем регистре (заглавная буква)?
boolean isSpaceChar(char)
Является ли символ пробелом или его аналогом (есть много невидимых символов)?
boolean isTitleCase(char)
Является ли символ титульным?

— Спасибо, Ким, думаю, некоторые из этих методов мне точно пригодятся.

Комментарии (21)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Denis Odesskiy Уровень 47
17 июня 2024
Класс Chrarcter не так прост (и там больше 11 000 строк кода😉), Ctrl+click на Chrarcter и посмотрите внимательно его внутренности. Опять же в лекции сильно упрощенный класс показан, чтобы показать саму суть, но потом лично я всегда заглядываю в реализацию класса... Он и документирован хорошо. Вообще Java так хорошо документирована, просто прелесть😀... Касательно Character[127 + 1]. Вот фрагмент кода, настоящего класса Chrarcter :

    private static class CharacterCache {
        private CharacterCache(){}

        static final Character[] cache;
        static Character[] archivedCache;

        static {
            int size = 127 + 1;

            // Load and use the archived cache if it exists
            VM.initializeFromArchive(CharacterCache.class);
            if (archivedCache == null || archivedCache.length != size) {
                Character[] c = new Character[size];
                for (int i = 0; i < size; i++) {
                    c[i] = new Character((char) i);
                }
                archivedCache = c;
            }
            cache = archivedCache;
        }
    }
Тут, как мне кажется: 1) Использование 127 + 1 четко показывает, что диапазон включает все значения от 0 до 127, подчеркивая, что 127 - это максимальное значение включаемого диапазона. 2) Это также может быть стилистическим выбором разработчика, чтобы сделать код более понятным для читающего.
Gans Electro Уровень 42
31 июля 2023
А почему

cache[] = new Character[127 + 1];
а не

cache[] = new Character[128]; //?
Роман Уровень 41
26 декабря 2023
Ответ от ChatGPT Оба варианта задают размер массива, равный 128 элементам. Это просто разные способы записать одну и ту же величину. В случае "new Character[127 + 1]", значение 127 + 1 вычисляется во время выполнения программы, в то время как "new Character[128]" задает размер массива непосредственно. Разницы в функциональности между ними нет - оба варианта инициализируют массив из 128 элементов.
Роман Уровень 41
26 декабря 2023
а может быть из-за того чтобы показать в примере понятнее, что 127 символов + 1 символ (нулевой в массиве), типо иначе в примере

 if (c <= 127)
   return cache[(int)c];
задались бы вопросом, почему 128
Илья Уровень 35
22 апреля 2021
Все методы из последней таблицы статические, чтобы не возникало непоняток, как у меня
Anonymous #1874460 Уровень 31
21 января 2020
Что значит титульный символ? boolean isTitleCase(char)
Евгений Уровень 41
20 июля 2020
Это некоторые символы в юникоде, как например, Dž или Lj - и это не два символа, а один. Вот тут их список.
PaiMei in J# Уровень 35
24 сентября 2021
5 из них на Latin, остальные на греческом))
Kurama Уровень 50
2 декабря 2022
В современной латыни такого нет (разве что латинские диграфы имеют эти свойства, например ae {æ}, но их в списке нет) p.s Стало интересно, погуглил про один из них: dž is the seventh letter of the Gaj's Latin alphabet for Serbo-Croatian (Bosnian, Croatian, Montenegrin and Serbian), after D and before Đ
Denis Odesskiy Уровень 47
17 июня 2024
Например:

public class CharType {

    public static void main(String[] args) {
        String str = getTitleString("   котопёс    ");
        System.out.println(str);
    }

    private static String getTitleString(String str) {
        if (str != null && str.length() > 0 && !str.isBlank()) {
            str = str.trim();
            char[] ch = str.toCharArray();
            ch[0] = Character.toTitleCase(ch[0]);
            str = String.valueOf(ch);
            return str;
        }
        return "";
    }
}
16 апреля 2018
Документация:

isJavaLetter(char ch)
Deprecated. 
Replaced by isJavaIdentifierStart(char).

isJavaLetterOrDigit(char ch)
Deprecated.
Replaced by isJavaIdentifierPart(char).
Максим Хоменко Уровень 36
17 марта 2017
Да именно так: строка 4544 класса Character, я проверил, но там есть ещё заполнение этого массива значениями,, что вероятно подразумевалось но не указывалось в этой лекции, и что меня несколько сбило с толку: static final Character cache[] = new Character[127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Character((char)i); }
MaxLich Уровень 40
22 мая 2017
Да, тоже удивился, откуда это он значения берёт, если код символа от 0 до 127, массив-то не инициализован значениями.
28 ноября 2017
Значит не один я такой зануда, залез и посмотрел где он там заполняется )))
NodeOne Уровень 41 Expert
2 сентября 2018
я не просто удивился, я решил что не понимаю нифига в очередной раз и схлопотал -20 к самооценке.
proxylunae Уровень 45
17 августа 2022
Ах, родственная душа!
Kirilo Lozitsky Уровень 40
17 марта 2017
static final Character cache[] = new Character[127 + 1]; Разве не Character[] cache должно бьіть?
MaxLich Уровень 40
11 мая 2017
Можно и так, и так писать (язык это поддерживает). Но принята запись, про которую Вы сказали
Даниил Уровень 41 Master
16 июня 2019
Более того, если двух мерный, то можно и такими способами:

Character[] cache[]
Character[][] cache
Character cache[][]
С трёх и более мерными массивами аналогично - вообще не принципиально где и сколько скобок ставить. Главное что бы их в сумме было столько какой глубины многомерности массив вам нужен. Ну и после открывающейся скобки она должна сразу закрыватся, вложенные скобки тут не катят (насколько я знаю).
20 ноября 2019
static final Character cache[] это С подобное объявление массива, ну так, для справки
Gans Electro Уровень 42
31 июля 2023
Character cache[] мне гораздо удобнее