Quantos caracteres uma String Java pode ter?

157

Estou tentando o problema do próximo palíndromo do Sphere Online Judge (SPOJ), onde preciso encontrar um palíndromo para um número inteiro de até um milhão de dígitos. Pensei em usar as funções do Java para reverter as Strings, mas elas permitiriam que uma String demorasse tanto?

andandandand
fonte
você está dizendo que precisa escrever uma função que gere palíndromos, cujo tamanho é especificado pelo usuário e pode ter até 1 milhão de caracteres?
Robert
3
O problema (do SPOJ) pode conter um arquivo 100Gigabyte e você deseja carregá-lo em uma sequência de uma vez? Sério ... por favor, use um scanner!
Grim

Respostas:

242

Você deve conseguir uma String de comprimento

  1. Integer.MAX_VALUEsempre 2.147.483.647 (2 31 - 1)
    (Definido pela especificação Java, o tamanho máximo de uma matriz, que a classe String usa para armazenamento interno)
    OU

  2. Half your maximum heap size(já que cada caractere tem dois bytes), o que for menor .

Bill the Lizard
fonte
43
... ou o seu tamanho máximo de heap dividido por 2 ... desde personagem é 2 bytes
ChssPly76
2
@ ChssPly76: Sim, está correto. Eu editei minha resposta, obrigado.
Bill Bill Lizard
2
como descubro o tamanho máximo de heap? Além disso, não sei qual máquina virtual java que o juiz está usando para testar meu problema é Integer.MAX_VALUE parte das especificações da JVM dependente?
andandandand
6
Integer.MAX_VALUE é sempre 2147483647 (2 ^ 31 - 1), isso faz parte da Especificação Java.
Cd1
4
Supondo uma JVM de 64 bits, já que você precisaria de 8 GB de memória virtual para armazenar uma sequência desse comprimento.
24310 Robert Fraser
21

Eu acredito que eles podem ter até 2 ^ 31-1 caracteres, pois são mantidos por uma matriz interna e as matrizes são indexadas por números inteiros em Java.

aperkins
fonte
A implementação interna é irrelevante - não há razão para que os dados dos caracteres não possam ser armazenados em uma matriz de longos, por exemplo. O problema é que a interface usa ints para comprimento. getBytese similares podem ter problemas se você tentar uma string muito grande.
Tom Hawtin # tackline 24/07/09
Isso é verdade - eu estava implicando esse fato. Foi mal.
24129 aperkins
15

Embora você possa, em teoria, caracteres Integer.MAX_VALUE, a JVM é limitada no tamanho da matriz que pode usar.

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);
        }
    }
}

no Oracle Java 8, atualização 92, impressões

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

Nota: no Java 9, Strings usará byte [], o que significa que caracteres de vários bytes usarão mais de um byte e reduzirão ainda mais o máximo. Se você tiver todos os quatro pontos de código de bytes, por exemplo, emojis, você receberá apenas 500 milhões de caracteres

Peter Lawrey
fonte
2
As Compact Strings no Java 9 usam a codificação Latin-1 ou UTF-16. Sem codificação de comprimento variável, ou seja, sem caracteres de três bytes.
apangin
@apangin "Não é um objetivo usar codificações alternativas, como UTF-8", obrigado pela correção.
Peter Lawrey
5

Você já pensou em usar seus números em BigDecimalvez de Stringretê- los ?

Thorbjørn Ravn Andersen
fonte
1
Depende do que o aplicativo fará com os números. Se for apenas para fazer coisas textuais, como encontrar palíndromos, contar dígitos (decimais), uma String será melhor. Se for fazer aritmética, um BigDecimal (ou BigInteger) é melhor.
Stephen C
O problema é "Para cada K, produza o menor palíndromo maior que K." (onde K é o número fornecido). Seria trivialmente simples produzir o primeiro palíndromo menor que K. Você precisa que a aritmética encontre um maior que K. Exemplo: Encontre o próximo palíndromo maior que 999999999999 ou o próximo palíndromo maior que 12922.
Thorbjørn Ravn Andersen
4

Integer.MAX_VALUE é o tamanho máximo da string + depende do tamanho da sua memória, mas no Problema do juiz on-line da esfera, você não precisa usar essas funções

Mite Mitreski
fonte
3

O Java9 usa o byte [] para armazenar o String.value, portanto, você pode obter apenas 1 GB de Strings no Java9. Por outro lado, o Java8 pode ter cadeias de caracteres de 2 GB.

Por caractere, quero dizer "char" s, algum caractere não é representável no BMP (como alguns dos emojis); portanto, serão necessários mais (atualmente 2) caracteres.

Revin
fonte
4
Você pode anexar referência para Java-9 limitar o tamanho da String para 1 GB de 2 GB
Aditya Gupta
-1

A parte da pilha piora, meus amigos. Não é garantido que o UTF-16 seja limitado a 16 bits e pode ser expandido para 32

Joe Plante
fonte
2
Exceto de Java chartipo é de 16 bits exatamente, por isso o número de bits UTF-16 usa realmente não importa ...
awksp