Сколько символов может иметь строка Java?
Я пытаюсь выполнить проблему Next Palindrome от Sphere Online Judge (SPOJ), где мне нужно найти палиндром для целого числа до миллион цифр. Я думал об использовании функций Java для обращения к строкам, но допустим ли они, что String будет такой длинной?
Вы говорите, что вам нужно написать функцию, которая генерирует палиндромы, размер которых определяется пользователем и может быть длиной до 1 миллиона символов?
Проблема (из SPOJ) может содержать файл размером 100 ГБ, и вам нравится загружать его сразу в строку? Серьезно . пожалуйста, используйте сканер!
8 ответов
Вы должны иметь возможность получить строку длины Integer.MAX_VALUE (всегда 2147483647 (2 31 — 1 ) по спецификации Java, максимальному размеру массива, который класс String использует для внутреннего хранилища) или половину вашего максимального размера кучи (поскольку каждый символ имеет два байта), в зависимости от того, что меньше.
как узнать максимальный размер кучи? Кроме того, я не знаю, какая виртуальная машина Java, используемая судьей для проверки моей проблемы, является Integer.MAX_VALUE частью спецификации JVM?
@CD1:dmindreader: Integer.MAX_VALUE является JVM независимым, так что вы всегда можете гарантировать , что это будет то же самое. @CD1: CD1: Спасибо за разъяснение, что, пока я был в АФК, я добавил его в свой ответ. 🙂
На самом деле вы хотите разделить вашу память на 4-6, так как вам нужен StringBuilder или что-то подобное для построения вашей String, т.е. в какой-то момент в памяти должно быть две копии. Если емкость вашего StringBuilder правильная, разделите на 4, но если его не разделить на 6, то безопаснее.
@Peter: Я не следую за тобой. Почему вы говорите: «В какой-то момент в памяти должно быть две копии»? Это связано с некоторыми ограничениями JVM, или вы говорите о реализации проблемы палиндрома, которую пытается решить dmindreader?
@ChssPly76: ChssPly76: действительно для текущих JVM, но вполне возможно создать JVM без максимального размера кучи. На самом деле это довольно просто: просто запросите больше памяти у ОС, когда заканчивается куча, и сборщик мусора не смог освободить необходимую память.
Java 9 собирается использовать один байт на символ для строк, имеющих только содержимое iso-latin-1, поэтому такие строки могут иметь столько же символов, сколько и куча в байтах (или максимальная длина массива, что бы меньше), но с другой стороны, поскольку нелатинские строки используют два байта в массиве, максимальная длина строки в Java 9 для них будет уменьшена вдвое, поддерживая только 1073741823 символа.
Я считаю, что они могут быть до 2 ^ 31-1 символов, поскольку они хранятся внутри внутреннего массива, а массивы индексируются целыми числами в Java.
Внутренняя реализация не имеет значения — нет причины, по которой, например, символьные данные не могут быть сохранены в массиве long. Проблема в том, что интерфейс использует целочисленные значения длины. getBytes и подобные могут иметь проблемы, если вы попытаетесь использовать очень большую строку.
Хотя вы можете в теории символов Integer.MAX_VALUE, JVM ограничен размером массива, который он может использовать.
public static void main(String. args) < for (int i = 0; i < 4; i++) < int len = Integer.MAX_VALUE - i; try < char[] ch = new char[len]; System.out.println("len: " + len + " OK"); >catch (Error e) < System.out.println("len: " + len + " " + e); >> >
на Oracle Java 8 обновление 92 печати
len: 2147483647 java.lang.OutOfMemoryError: Requested array size exceeds VM limit len: 2147483646 java.lang.OutOfMemoryError: Requested array size exceeds VM limit len: 2147483645 OK len: 2147483644 OK
Примечание: в Java 9 строки будут использовать байт [], что будет означать, что многобайтовые символы будут использовать более одного байта и максимально уменьшить максимум. Если у вас есть все четыре байтовых кодовых пункта, например. emojis, вы получите всего около 500 миллионов символов.
Компактные строки в Java 9 используют кодировку Latin-1 или UTF-16. Нет кодирования переменной длины, то есть нет трехбайтовых символов.
String максимальное количество символов java
Learn Latest Tutorials
Preparation
Trending Technologies
B.Tech / MCA
Javatpoint Services
JavaTpoint offers too many high quality services. Mail us on h[email protected], to get more information about given services.
- Website Designing
- Website Development
- Java Development
- PHP Development
- WordPress
- Graphic Designing
- Logo
- Digital Marketing
- On Page and Off Page SEO
- PPC
- Content Development
- Corporate Training
- Classroom and Online Training
- Data Entry
Training For College Campus
JavaTpoint offers college campus training on Core Java, Advance Java, .Net, Android, Hadoop, PHP, Web Technology and Python. Please mail your requirement at [email protected].
Duration: 1 week to 2 week
Like/Subscribe us for latest updates or newsletter
Строка Максимальная длина в Java – метод length()
Мой вопрос очень простой, но я не нашел ответа на поиск в Google.
В Java, каков максимальный размер объекта String , ссылаясь на вызов метода length() ?
Я знаю, что length() возвращает размер String как char [] ;
Учитывая String class ‘ length возвращает int , максимальная длина, возвращаемая методом, будет Integer.MAX_VALUE , которая равна 2^31 — 1 (или около 2 миллиардов.)
В терминах длины и индексации массивов (например, char[] , что, вероятно, является способом представления внутренних данных для String s), Глава 10: Массивы Спецификация Java Language, Java SE 7 Edition гласит следующее:
Переменные, содержащиеся в массиве не имеют имен; вместо этого они ссылки на выражения доступа к массиву которые используют неотрицательный целочисленный индекс значения. Эти переменные называются компоненты массива. Если массив имеет компоненты n , мы говорим, что n – это длина массива; компоненты массив ссылается с использованием целого числа индексы от 0 до n — 1 включительно.
Кроме того, индексирование должно иметь значения int , как указано в Раздел 10.4:
Массивы должны индексироваться значениями int ;
Следовательно, оказывается, что предел действительно 2^31 — 1 , так как это максимальное значение для неотрицательного значения int .
Однако, вероятно, будут другие ограничения, такие как максимальный размер выделяемого массива.
Так как массивы должны индексироваться с целыми числами, максимальная длина массива равна Integer.MAX_INT (2 31 -1 или 2 147 483 647). Это предполагает, что у вас достаточно памяти для хранения массива такого размера, конечно.
java.io.DataInput.readUTF() и java.io.DataOutput.writeUTF(String) говорят, что объект String представлен двумя байтами информации о длине и измененным UTF-8 представление каждого символа в строке. Это делает вывод о том, что длина строки ограничена количеством байтов модифицированного представления строки UTF-8 при использовании с DataInput и DataOutput .
Кроме того, Спецификация CONSTANT_Utf8_info , найденная в спецификации виртуальной машины Java, определяет структуру следующим образом.
Вы можете найти, что размер “длина” два байта.
То, что тип возврата определенного метода (например, String.length() ) составляет int , не всегда означает, что его допустимое максимальное значение равно Integer.MAX_VALUE . Вместо этого, в большинстве случаев, int выбирается только по соображениям производительности. Спецификация языка Java говорит, что целые числа, размер которых меньше, чем int , преобразуются в int перед вычислением (если моя память служит мне правильно), и это одна из причин выбора int , когда нет особой причины.
Максимальная длина во время компиляции не более 65536. Заметим еще раз, что длина представляет собой количество байтов измененного представления UTF-8, а не количество символов в объекте String .
String объекты могут иметь гораздо больше символов во время выполнения. Однако, если вы хотите использовать объекты String с интерфейсами DataInput и DataOutput , лучше избегать использования слишком длинных объектов String . Я нашел это ограничение, когда я внедрил Objective-C эквиваленты DataInput.readUTF() и DataOutput.writeUTF(String) .
по-видимому, он связан с int, который равен 0x7FFFFFFF (2147483647).
Тип возвращаемого значения метода length() класса String int.
Таким образом, максимальное значение int 2147483647.
Строка считается внутренним массивом char, поэтому индексирование выполняется в пределах максимального диапазона.
Это означает, что мы не можем индексировать 2147483648-й член. Таким образом, максимальная длина строки в java равна 2147483647.
Примитивный тип данных int – 4 байта (32 бита) в java. В качестве знакового бита используется 1 бит (MSB). Диапазон ограничен в пределах от -2 ^ 31 до 2 ^ 31-1 (-2147483648 до 2147483647).).
Мы не можем использовать отрицательные значения для индексации. Очевидно, что диапазон, который мы можем использовать, составляет от 0 до 2147483647.
У меня есть iMac 2010 года с 8 ГБ ОЗУ, запускающий Eclipse Neon.2 Release (4.6.2) с Java 1.8.0_25. С аргументом VM -Xmx6g я выполнил следующий код:
StringBuilder sb = new StringBuilder(); for (int i = 0; i < Integer.MAX_VALUE; i++) < try < sb.append('a'); >catch (Throwable e) < System.out.println(i); break; >> System.out.println(sb.toString().length());
Requested array size exceeds VM limit 1207959550
Итак, кажется, что максимальный размер массива составляет ~ 1207,959,549. Затем я понял, что на самом деле нам неинтересно, что в Java заканчивается память: мы просто ищем максимальный размер массива (который, как представляется, определен как константа). Итак:
for (int i = 0; i < 1_000; i++) < try < char[] array = new char[Integer.MAX_VALUE - i]; Arrays.fill(array, 'a'); String string = new String(array); System.out.println(string.length()); >catch (Throwable e) < System.out.println(e.getMessage()); System.out.println("Last: " + (Integer.MAX_VALUE - i)); System.out.println("Last: " + i); >>
Requested array size exceeds VM limit Last: 2147483647 Last: 0 Requested array size exceeds VM limit Last: 2147483646 Last: 1 Java heap space Last: 2147483645 Last: 2
Итак, кажется, что max является Integer.MAX_VALUE – 2, или (2 ^ 31) – 3
P.S. Я не уверен, почему мой StringBuilder достиг максимума в 1207959550 , а мой char[] превысил отметку (2 ^ 31) -3. Кажется, что AbstractStringBuilder удваивает размер своего внутреннего char[] , чтобы увеличить его, что, вероятно, вызывает проблему.