Chuỗi Java có thể có bao nhiêu ký tự?


157

Tôi đang thử vấn đề Palindrom tiếp theo từ Thẩm phán trực tuyến Sphere (SPOJ) trong đó tôi cần tìm một bảng màu cho số nguyên lên tới một triệu chữ số. Tôi đã nghĩ về việc sử dụng các hàm của Java để đảo ngược Chuỗi, nhưng liệu chúng có cho phép một Chuỗi dài như vậy không?


bạn đang nói rằng bạn cần phải viết một hàm tạo ra các palindromes, kích thước của nó được người dùng chỉ định và có thể dài tới 1 triệu ký tự?
Robert

3
Các vấn đề (từ SPOJ) có thể chứa một tập tin 100Gigabyte, và bạn muốn tải nó thành một chuỗi cùng một lúc? Nghiêm túc ... vui lòng sử dụng Máy quét!
Grim

Câu trả lời:


242

Bạn sẽ có thể có được một chuỗi độ dài

  1. Integer.MAX_VALUEluôn luôn 2.147.483.647 (2 31 - 1)
    (Được xác định bởi đặc tả Java, kích thước tối đa của một mảng, mà lớp String sử dụng để lưu trữ nội bộ)
    HOẶC

  2. Half your maximum heap size(vì mỗi ký tự là hai byte) tùy theo giá trị nào nhỏ hơn .


43
... hoặc kích thước heap tối đa của bạn chia cho 2 ... vì ký tự là 2 byte
ChssPly76

2
@ ChssPly76: Vâng, đúng vậy. Tôi chỉnh sửa câu trả lời của tôi, cảm ơn bạn.
Lập hóa đơn cho thằn lằn

2
Làm thế nào để tôi tìm ra kích thước heap tối đa? Ngoài ra, tôi không biết máy ảo java nào mà thẩm phán đang sử dụng để kiểm tra vấn đề của tôi là Integer.MAX_VALUE một phần của thông số phụ thuộc JVM?
andandand và

6
Integer.MAX_VALUE luôn là 2147483647 (2 ^ 31 - 1), đó là một phần của Đặc tả Java.
cd1

4
Giả sử JVM 64 bit, vì bạn cần 8GB bộ nhớ ảo để lưu trữ một chuỗi có độ dài đó.
Robert Fraser

21

Tôi tin rằng chúng có thể có tối đa 2 ^ 31-1 ký tự, vì chúng được giữ bởi một mảng bên trong và các mảng được lập chỉ mục bởi các số nguyên trong Java.


Việc triển khai nội bộ là không liên quan - chẳng hạn, không có lý do nào khiến dữ liệu ký tự không thể được lưu trữ trong một mảng dài. Vấn đề là giao diện sử dụng ints cho chiều dài. getBytesvà tương tự có thể có vấn đề nếu bạn cố gắng cho một chuỗi rất lớn.
Tom Hawtin - tackline

Đó là sự thật - tôi đã ngụ ý thực tế đó. Lỗi của tôi.
rượu khai vị

15

Trong lý thuyết bạn có thể về các ký tự Integer.MAX_VALUE, JVM bị giới hạn về kích thước của mảng mà nó có thể sử dụng.

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

trên Oracle Java 8 cập nhật 92 bản in

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

Lưu ý: trong Java 9, Chuỗi sẽ sử dụng byte [], điều đó có nghĩa là các ký tự nhiều byte sẽ sử dụng nhiều hơn một byte và giảm tối đa hơn nữa. Nếu bạn có tất cả bốn điểm mã byte, ví dụ như biểu tượng cảm xúc, bạn sẽ chỉ nhận được khoảng 500 triệu ký tự


2
Chuỗi nhỏ gọn trong Java 9 sử dụng mã hóa Latin-1 hoặc UTF-16. Không có mã hóa độ dài thay đổi, nghĩa là không có ba ký tự byte.
apangin

@apangin "Không phải là mục tiêu để sử dụng các bảng mã thay thế như UTF-8" cảm ơn bạn đã sửa chữa.
Peter Lawrey

5

Bạn đã cân nhắc sử dụng BigDecimalthay vì Stringgiữ số của mình chưa?


1
Nó phụ thuộc vào những gì ứng dụng sẽ làm với các con số. Nếu nó sẽ chỉ làm những việc văn bản như tìm palindromes, đếm các chữ số (thập phân), thì một Chuỗi là tốt hơn. Nếu nó sẽ được thực hiện số học, một BigDecimal (hoặc BigInteger) sẽ tốt hơn.
Stephen C

Vấn đề là "Với mỗi K, xuất ra palindrom nhỏ nhất lớn hơn K." (trong đó K là số đã cho). Sẽ rất đơn giản để tạo ra bảng màu đầu tiên nhỏ hơn K. Bạn yêu cầu số học để tìm một số lớn hơn K. Ví dụ: Tìm bảng màu tiếp theo lớn hơn 999999999999 hoặc bảng màu tiếp theo lớn hơn 12922.
Thorbjørn Ravn Andersen

4

Integer.MAX_VALUE là kích thước tối đa của chuỗi + phụ thuộc vào kích thước bộ nhớ của bạn nhưng Vấn đề về thẩm phán trực tuyến của hình cầu bạn không phải sử dụng các chức năng đó


3

Java9 sử dụng byte [] để lưu trữ String.value, do đó bạn chỉ có thể nhận được khoảng 1GB Chuỗi trong Java9. Mặt khác, Java8 có thể có Chuỗi 2GB.

Theo ký tự tôi có nghĩa là "char", một số ký tự không thể biểu thị trong BMP (như một số biểu tượng cảm xúc), do đó, sẽ mất nhiều ký tự (hiện tại là 2).


4
Bạn có thể đính kèm tham chiếu cho kích thước Chuỗi giới hạn Java-9 lên 1 GB từ 2 GB không
Aditya Gupta

-1

Các phần heap trở nên tồi tệ hơn, các bạn của tôi. UTF-16 không được đảm bảo giới hạn ở 16 bit và có thể mở rộng lên 32


2
Ngoại trừ charloại của Java chính xác là 16 bit, vì vậy số lượng bit mà UTF-16 sử dụng không thực sự quan trọng ...
awksp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.