Berapa banyak karakter yang dapat dimiliki Java String?

157

Saya mencoba masalah The Next Palindrome dari Sphere Online Judge (SPOJ) di mana saya perlu menemukan palindrome untuk bilangan bulat hingga satu juta digit. Saya berpikir tentang menggunakan fungsi Java untuk membalikkan Strings, tetapi apakah mereka mengizinkan String menjadi selama ini?

andandandand
sumber
apakah Anda mengatakan bahwa Anda perlu menulis fungsi yang menghasilkan palindrom, yang ukurannya ditentukan pengguna dan panjangnya bisa hingga 1 juta karakter?
Robert
3
The Masalah (dari SPOJ) mungkin berisi file 100Gigabyte, dan Anda ingin memuatnya ke dalam string sekaligus? Serius ... silakan gunakan Scanner!
Grim
Kemungkinan duplikat dari String's Maximum length in Java - calling length ()
Bergi

Jawaban:

242

Anda harus bisa mendapatkan String of length

  1. Integer.MAX_VALUEselalu 2.147.483.647 (2 31 - 1)
    (Didefinisikan oleh spesifikasi Java, ukuran maksimum array, yang digunakan kelas String untuk penyimpanan internal)
    ATAU

  2. Half your maximum heap size(karena setiap karakter adalah dua byte) yang lebih kecil .

Bill the Lizard
sumber
43
... atau ukuran heap maksimum Anda dibagi 2 ... karena karakter adalah 2 byte
ChssPly76
2
@ ChssPly76: Ya, itu benar. Saya mengedit jawaban saya, terima kasih.
Bill the Lizard
2
bagaimana cara mengetahui ukuran tumpukan maksimum? Juga, saya tidak tahu mesin virtual java mana yang digunakan hakim untuk menguji masalah saya apakah Integer.MAX_VALUE bagian dari spesifikasi JVM dependen?
andandandand
6
Integer.MAX_VALUE selalu 2147483647 (2 ^ 31 - 1), itu bagian dari Spesifikasi Java.
cd1
4
Dengan asumsi JVM 64-bit, karena Anda membutuhkan memori virtual 8GB untuk menyimpan string sepanjang itu.
Robert Fraser
21

Saya percaya mereka bisa sampai 2 ^ 31-1 karakter, karena mereka dipegang oleh array internal, dan array diindeks oleh bilangan bulat di Jawa.

aperkins
sumber
Implementasi internal tidak relevan - tidak ada alasan mengapa data karakter tidak dapat disimpan dalam array yang panjang, misalnya. Masalahnya adalah antarmuka menggunakan int untuk panjang. getBytesdan yang serupa mungkin memiliki masalah jika Anda mencoba untuk string yang sangat besar.
Tom Hawtin - tackline
Itu benar - saya menyiratkan fakta itu. Salahku.
aperkins
15

Meskipun Anda bisa dalam teori Integer.MAX_VALUE karakter, JVM terbatas dalam ukuran array yang dapat digunakan.

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

pada Oracle Java 8 perbarui 92 cetakan

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

Catatan: di Java 9, Strings akan menggunakan byte [] yang berarti bahwa karakter multi-byte akan menggunakan lebih dari satu byte dan mengurangi maksimum lebih lanjut. Jika Anda memiliki keempat titik kode byte misalnya emoji, Anda hanya akan mendapatkan sekitar 500 juta karakter

Peter Lawrey
sumber
2
Compact Strings in Java 9 menggunakan pengkodean Latin-1 atau UTF-16. Tidak ada pengkodean panjang variabel, yaitu, tidak ada karakter tiga byte.
apangin
@apangin "Ini bukan tujuan untuk menggunakan pengkodean alternatif seperti UTF-8" terima kasih atas koreksi.
Peter Lawrey
5

Sudahkah Anda mempertimbangkan untuk menggunakan BigDecimalalih-alih Stringmemegang nomor Anda?

Thorbjørn Ravn Andersen
sumber
1
Itu tergantung pada apa yang akan dilakukan aplikasi dengan angka. Jika itu hanya akan melakukan hal-hal tekstual seperti menemukan palindrom, menghitung angka (desimal), maka sebuah String lebih baik. Jika akan melakukan aritmatika, BigDecimal (atau BigInteger) lebih baik.
Stephen C
Masalahnya adalah "Untuk setiap K, hasilkan palindrom terkecil yang lebih besar dari K." (di mana K adalah nomor yang diberikan). Akan sangat mudah untuk mengeluarkan palindrom pertama yang lebih kecil dari K. Anda memerlukan aritmatika untuk menemukan yang lebih besar dari K. Contoh: Temukan palindrom berikutnya yang lebih besar dari 999999999999, atau palindrom berikutnya yang lebih besar dari 12922.
Thorbjørn Ravn Andersen
4

Integer.MAX_VALUE adalah ukuran maksimum string + tergantung dari ukuran memori Anda, tetapi Masalah pada sphere online menilai Anda tidak harus menggunakan fungsi-fungsi tersebut

Tungau Mitreski
sumber
3

Java9 menggunakan byte [] untuk menyimpan String.value, jadi Anda hanya bisa mendapatkan sekitar 1GB Strings di Java9. Java8 di sisi lain dapat memiliki 2GB Strings.

Dengan karakter yang saya maksud "char", beberapa karakter tidak dapat diwakili dalam BMP (seperti beberapa emoji), sehingga akan membutuhkan lebih banyak (saat ini 2) karakter.

Revin
sumber
4
Bisakah Anda lampirkan referensi untuk ukuran String Java-9 yang membatasi hingga 1 GB dari 2 GB
Aditya Gupta
-1

Bagian tumpukan semakin parah, teman-teman saya. UTF-16 tidak dijamin terbatas pada 16 bit dan dapat diperluas hingga 32 bit

Joe Plante
sumber
2
Kecuali chartipe Java sebenarnya 16 bit, jadi jumlah bit yang digunakan UTF-16 tidak terlalu masalah ...
awksp