Wie viele Zeichen kann ein Java-String haben?

157

Ich versuche das Next Palindrome- Problem von Sphere Online Judge (SPOJ), bei dem ich ein Palindrom für eine ganze Zahl von bis zu einer Million Stellen finden muss. Ich habe darüber nachgedacht, Javas Funktionen zum Umkehren von Strings zu verwenden, aber würden sie zulassen, dass ein String so lang ist?

andandandand
quelle
Wollen Sie damit sagen, dass Sie eine Funktion schreiben müssen, die Palindrome generiert, deren Größe vom Benutzer angegeben wird und die bis zu 1 Million Zeichen lang sein kann?
Robert
3
Das Problem (von SPOJ) enthält möglicherweise eine 100-Gigabyte-Datei, und Sie möchten sie sofort in eine Zeichenfolge laden? Im Ernst ... bitte benutzen Sie einen Scanner!
Grim
Mögliches Duplikat der maximalen Länge
Bergi

Antworten:

242

Sie sollten in der Lage sein, einen String mit einer Länge zu erhalten

  1. Integer.MAX_VALUEimmer 2.147.483.647 (2 31 - 1)
    (Definiert durch die Java-Spezifikation die maximale Größe eines Arrays, die die String-Klasse für den internen Speicher verwendet)
    ODER

  2. Half your maximum heap size(da jedes Zeichen zwei Bytes hat) je nachdem, welcher Wert kleiner ist .

Bill die Eidechse
quelle
43
... oder Ihre maximale Heap-Größe geteilt durch 2 ... da das Zeichen 2 Bytes
beträgt
2
@ ChssPly76: Ja, das ist richtig. Ich habe meine Antwort bearbeitet, danke.
Bill the Lizard
2
Wie finde ich die maximale Heap-Größe heraus? Außerdem weiß ich nicht, welche virtuelle Java-Maschine der Richter zum Testen meines Problems verwendet. Ist Integer.MAX_VALUE Teil der Spezifikation von JVM?
andandandand
6
Integer.MAX_VALUE ist immer 2147483647 (2 ^ 31 - 1), das ist Teil der Java-Spezifikation.
CD1
4
Angenommen, eine 64-Bit-JVM, da Sie 8 GB virtuellen Speicher benötigen, um eine Zeichenfolge dieser Länge zu speichern.
Robert Fraser
21

Ich glaube, sie können bis zu 2 ^ 31-1 Zeichen enthalten, da sie von einem internen Array gehalten werden und Arrays in Java durch Ganzzahlen indiziert werden.

Aperkins
quelle
Die interne Implementierung ist irrelevant - es gibt keinen Grund, warum die Zeichendaten beispielsweise nicht in einem Array von Longs gespeichert werden könnten. Das Problem ist, dass die Schnittstelle Ints für die Länge verwendet. getBytesund ähnliches kann Probleme haben, wenn Sie versuchen, eine sehr große Zeichenfolge zu verwenden.
Tom Hawtin - Tackline
Das ist wahr - ich habe diese Tatsache impliziert. Mein Fehler.
Aperkins
15

Während Sie theoretisch Integer.MAX_VALUE-Zeichen verwenden können, ist die JVM in der Größe des Arrays begrenzt, das sie verwenden kann.

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

unter Oracle Java 8 Update 92 druckt

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

Hinweis: In Java 9 verwenden Strings Byte [], was bedeutet, dass Mehrbytezeichen mehr als ein Byte verwenden und das Maximum weiter reduzieren. Wenn Sie alle vier Byte-Codepunkte haben, z. B. Emojis, erhalten Sie nur etwa 500 Millionen Zeichen

Peter Lawrey
quelle
2
Kompakte Zeichenfolgen in Java 9 verwenden entweder Latin-1- oder UTF-16-Codierung. Keine Codierung mit variabler Länge, dh keine Drei-Byte-Zeichen.
Apangin
@apangin "Es ist kein Ziel, alternative Codierungen wie UTF-8 zu verwenden", danke für die Korrektur.
Peter Lawrey
5

Haben Sie darüber nachgedacht , Ihre Nummern zu verwenden, BigDecimalanstatt sie Stringzu halten?

Thorbjørn Ravn Andersen
quelle
1
Es hängt davon ab, was die Anwendung mit den Zahlen machen wird. Wenn es nur um Textaufgaben wie das Auffinden von Palindromen und das Zählen von (Dezimal-) Ziffern geht, ist ein String besser. Wenn es um Arithmetik geht, ist ein BigDecimal (oder BigInteger) besser.
Stephen C
Das Problem ist "Geben Sie für jedes K das kleinste Palindrom aus, das größer als K ist." (wobei K die angegebene Zahl ist). Es wäre trivial einfach, das erste Palindrom kleiner als K auszugeben. Sie benötigen eine Arithmetik, um ein Palindrom größer als K zu finden. Beispiel: Finden Sie das nächste Palindrom größer als 999999999999 oder das nächste Palindrom größer als 12922.
Thorbjørn Ravn Andersen
4

Integer.MAX_VALUE ist die maximale Größe des Strings + hängt von Ihrer Speichergröße ab, aber das Problem bei der Online-Beurteilung von Sphere ist, dass Sie diese Funktionen nicht verwenden müssen

Milbe Mitreski
quelle
3

Java9 verwendet byte [] zum Speichern von String.value, sodass Sie in Java9 nur etwa 1 GB Strings erhalten können. Java8 kann dagegen 2 GB Strings haben.

Mit Zeichen meine ich "Zeichen", einige Zeichen sind in BMP nicht darstellbar (wie einige der Emojis), daher werden mehr (derzeit 2) Zeichen benötigt.

Revin
quelle
4
Könnten Sie eine Referenz für Java-9 anhängen, die die Zeichenfolgengröße von 2 GB auf 1 GB begrenzt
Aditya Gupta
-1

Der Haufen wird schlimmer, meine Freunde. UTF-16 ist nicht auf 16 Bit beschränkt und kann auf 32 erweitert werden

Joe Plante
quelle
2
Außer, dass Javas charTyp genau 16 Bit ist, spielt die Anzahl der von UTF-16 verwendeten Bits keine Rolle ...
awksp