Почему классы String, StringBuffer и StringBuilder используют байтовый массив вместо символьного массива для хранения символов строки? - PullRequest
0 голосов
/ 10 января 2019

Байт не может вместить юникоды символов из разных языков мира. Таким образом, используя байтовый массив, мы не можем иметь строку разных языков. Почему эти классы используют байтовый массив вместо символьного массива?

UPDATE:

class First
{
        public static void main(String[] args)
        {
                System.out.println();
                String s = "\u0935\u0902\u0926\u0947 \u092e\u093e\u0924\u0930\u092e\u094d";
                String s1 = "वंदे मातरम्";
                System.out.println(sb);
                System.out.println(sb1);
        }
}

Я думаю, что выше строки занимают два байта для каждого символа. Как их можно разместить в одном байте?

Ответы [ 4 ]

0 голосов
/ 23 января 2019

На самом деле класс String в Java 9 и более поздних версиях Java может использовать 1-байтовый или 2-байтовый массив байтов для каждого символа в зависимости от содержимого строки. В String.java есть поле

private final byte coder;

Что определяет кодировку, используемую символами в строке (LATIN1 или UTF16).

0 голосов
/ 10 января 2019

Байт не может вместить юникоды символов из различных языки мира. Таким образом, используя байтовый массив, мы не можем иметь строку разных языков.

Чар не может, так как они только 16-битные. Для этого вам понадобится int. Но int на персонажа кажется слишком расточительным.

Почему эти классы используют байтовый массив вместо символьного массива?

Прежде всего очень мало строк о словах, взятых из разговорного языка. Это почти весь компьютерный код, использующий исключительно символы ASCII, который может быть закодирован в 7 бит. Использование 16 или более битов для каждого символа очень бесполезно для памяти. Вместо этого они кодируют его в байтах, либо ASCII, если все символы ASCII, либо UTF-16, если некоторые символы не являются. Это сохраняет память, когда она может, и остается достаточно хорошей, когда она не может.

0 голосов
/ 10 января 2019

Использование byte[] - это оптимизация, представленная в Java 9. Цели / мотивация этого изменения описаны в JEP 254: Compact Strings .

Резюме

Принять более компактное внутреннее представление для строк.

Цель

Повышение эффективности использования пространства классом String и связанными с ним классами при сохранении производительности в большинстве сценариев и сохранении полной совместимости для всех связанных Java и нативных интерфейсов.

Non-цели

Не стоит использовать альтернативные кодировки, такие как UTF-8, для внутреннего представления строк. Последующий JEP может изучить этот подход.

Мотивация

Текущая реализация класса String хранит символы в массиве символов, используя два байта (шестнадцать бит) для каждого символа. Данные, собранные из разных приложений, указывают на то, что строки являются основным компонентом использования кучи и, более того, что большинство объектов String содержат только символы Latin-1. Для таких символов требуется только один байт, поэтому половина пространства во внутренних массивах таких объектов String не используется.

Описание

Мы предлагаем изменить внутреннее представление класса String с массива символов UTF-16 на байтовый массив плюс поле флага кодирования. Новый класс String будет хранить символы, закодированные как ISO-8859-1 / Latin-1 (один байт на символ), или как UTF-16 (два байта на символ) в зависимости от содержимого строки. Флаг кодирования будет указывать, какая кодировка используется.

Классы, связанные со строками, такие как AbstractStringBuilder, StringBuilder и StringBuffer, будут обновлены для использования того же представления, что и встроенные строковые операции виртуальной машины HotSpot.

Это чисто изменение реализации, без изменений существующих открытых интерфейсов. Не планируется добавлять какие-либо новые публичные API или другие интерфейсы.

Проделанная до настоящего времени работа по созданию прототипа подтверждает ожидаемое сокращение объема памяти, существенное снижение активности GC и незначительные регрессии производительности в некоторых угловых случаях.

0 голосов
/ 10 января 2019

В качестве оптимизации некоторые реализации виртуальных машин (например, OpenJDK 9 и выше ) хранят строки, состоящие только из ASCII-кодируемых символов в байтовых массивах, что экономит примерно половину пространства по сравнению с использованием char[].

И поскольку String часто используется для технических вещей (в отличие от естественного языка), большинство значений String в большинстве программ соответствуют этому описанию (даже когда код обрабатывает язык, который не используйте кодировку ASCII (например, арабский или японский). HTML-теги, идентификаторы логгера, выходные данные отладки и подобные вещи всегда могут использовать эти сжатые строки.

Поскольку нет (официального, поддерживаемого) способа на самом деле получить доступ к необработанным данным, и весь доступ должен пройти через методы, это обычно не вызывает проблем совместимости.

...