【问题标题】:How many characters can a Java String have?Java 字符串可以有多少个字符?
【发布时间】:2010-11-13 21:05:21
【问题描述】:

我正在尝试来自 Sphere Online Judge (SPOJ) 的The Next Palindrome 问题,我需要在其中找到最多一百万位整数的回文。我考虑过使用 Java 的函数来反转字符串,但它们会允许字符串这么长吗?

【问题讨论】:

  • 你是说需要编写一个生成回文的函数,回文的大小由用户指定,最长可达100万个字符?
  • 问题(来自 SPOJ)可能包含一个 100G 的文件,您想一次将它加载到一个字符串中吗?说真的……请使用扫描仪!

标签: java string


【解决方案1】:

你应该能够得到一个长度的字符串

  1. Integer.MAX_VALUE 总是 2,147,483,647 (231 - 1)
    (由 Java 规范定义,数组的最大大小,String 类用于内部存储)
    或者

  2. Half your maximum heap size(因为每个字符是两个字节)以较小者为准

【讨论】:

  • ... 或者你的最大堆大小除以 2 ... 因为字符是 2 个字节
  • @ChssPly76:是的,没错。我编辑了我的答案,谢谢。
  • Integer.MAX_VALUE 总是 2147483647 (2^31 - 1),这是 Java 规范的一部分。
  • 假设是 64 位 JVM,因为您需要 8GB 的​​虚拟内存来存储该长度的字符串。
  • Java 9 将对只有 iso-latin-1 内容的字符串的每个字符使用一个字节,因此此类字符串可以具有与堆字节数一样多的字符(或最大数组长度,无论如何更小),但另一方面,由于非拉丁字符串在数组中使用两个字节,因此在 Java 9 中它们的最大字符串长度将减半,仅支持 1073741823 个字符。
【解决方案2】:

我相信它们最多可以包含 2^31-1 个字符,因为它们由内部数组保存,并且数组在 Java 中由整数索引。

【讨论】:

  • 内部实现无关紧要 - 例如,没有理由不能将字符数据存储在 long 数组中。问题是接口使用整数作为长度。如果您尝试使用非常大的字符串,getBytes 和类似的可能会出现问题。
  • 这是真的——我是在暗示这个事实。我的错。
【解决方案3】:

虽然理论上您可以使用 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 中,字符串将使用 byte[],这意味着多字节字符将使用多个字节并进一步减少最大值。如果您拥有所有四个字节代码点,例如emojis,你只会得到大约 5 亿个字符

【讨论】:

  • Compact Strings 在 Java 9 中使用 Latin-1 或 UTF-16 编码。无变长编码,即无三字节字符。
  • @apangin “使用 UTF-8 等替代编码不是目标”谢谢您的更正。
【解决方案4】:

您是否考虑过使用BigDecimal 而不是String 来保存您的号码?

【讨论】:

  • 这取决于应用程序将如何处理这些数字。如果它只做文本的事情,比如查找回文、计算(十进制)数字,那么字符串会更好。如果要进行算术运算,BigDecimal(或 BigInteger)会更好。
  • 问题是“对于每个K,输出大于K的最小回文数”。 (其中 K 是给定的数字)。输出第一个小于 K 的回文非常简单。您需要算术才能找到大于 K 的回文。示例:查找下一个大于 999999999999 的回文,或下一个大于 12922 的回文。
【解决方案5】:

Integer.MAX_VALUE 是字符串的最大大小 + 取决于您的内存大小,但是 sphere 的在线问题判断您不必使用这些函数

【讨论】:

    【解决方案6】:

    Java9 使用 byte[] 来存储 String.value,所以在 Java9 中只能获取大约 1GB 的字符串。另一方面,Java8 可以有 2GB 的字符串。

    我的意思是“字符”,某些字符在 BMP 中无法表示(如某些表情符号),因此需要更多(目前为 2 个)字符。

    【讨论】:

    • 能否附上 Java-9 限制字符串大小从 2 GB 到 1 GB 的参考
    【解决方案7】:

    朋友们,堆部分变得更糟了。 UTF-16 不保证限制为 16 位,可以扩展到 32 位

    【讨论】:

    • 除了 Java 的 char 类型正好是 16 位,所以 UTF-16 使用的位数并不重要...
    • @awksp: char 是 16 位,但是 String 中的 字符 可以占用 两个 char 的(两个'surrogate' 代码元素以表示 UTF16 中的一个字符)。但是,Q 仅适用于十进制数字,这些不仅是 BMP,而且是 8859-1/block0 和 ASCII。
    猜你喜欢
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多