Java:具有长类型参数的 String.substring()

Posted

技术标签:

【中文标题】Java:具有长类型参数的 String.substring()【英文标题】:Java: String.substring() with long type parameters 【发布时间】:2011-04-16 05:21:25 【问题描述】:

我有一个大字符串(更准确地说是 RSS 文章),我想在特定的 startIndex 和 endIndex 中获取单词。 String 提供了 substring 方法,但仅使用 int 作为其参数。我的开始和结束索引是 long 类型。

使用 long 类型的开始和结束索引从字符串中获取单词的最佳方法是什么?

我的第一个解决方案是开始修剪字符串并将其取下,以便我可以使用整数。不喜欢它要去的地方。然后我查看了Apache Commons Lang,但没有找到任何东西。有什么好的解决办法吗?

谢谢。


更新:

只是为了提供更多信息。

我正在使用一个名为General Architecture for Text Engineering (GATE) 的工具,它扫描一个字符串并返回一个注释列表。注释包含一个单词的类型(Person、Location 等)以及该单词的开始和结束索引。

对于 RSS,我使用 ROME,它读取 RSS 提要并在字符串中包含文章正文。

【问题讨论】:

为什么不分块读取数据集并使用常规子字符串(int,int)? 出于好奇,这些字符串到底有多大? 你真的得到了 8 GB 的 RSS 文章吗?? @Sagar 是的,我也想过。但我想也许有更好的方法(不确定到底有多好:P)。 @Pointy & @Roman :S 我从来没有想过要实际计算大小,但问题是,我使用一个库来扫描文本并为我提供某些单词的索引(不是实际单词!)。这些索引的类型为 long。我很确定它没有那么大...... 【参考方案1】:

在 String 上执行此操作毫无意义,因为 String 可以容纳 2^31 - 1 个字符。在内部,字符串的字符保存在 char[] 中,所有 API 方法都使用 int 作为长度、位置和偏移量的类型。

适用于 StringBuffer 或 StringBuilder 的相同限制;即int 长度。 StringReader 由 String 支持,因此无济于事。 CharBuffer 和 ByteBuffer 有相同的限制;即int 长度。 原始类型的裸数组限制为 int 长度。

简而言之,您将不得不实现自己的“长字符串”类型,该类型在内部将其字符保存在(例如)一个字符数组的数组中。

(我尝试了谷歌搜索,但我找不到看起来可信的长字符串的现有实现。我想在 Java 中没有太多对大字符串的调用......)

顺便说一句,如果您预计字符串永远不会这么大,您应该将long 偏移量转换为int。强制转换可以工作,但您可能需要检查范围并在获得偏移量 >= 2^31 时抛出异常。

【讨论】:

【参考方案2】:

Stringchar[] 支持,并且数组只能使用 ints 进行索引(因此只能容纳 231 个字符)。如果您有long 索引,只需将它们转换为ints - 如果它们大于Integer.MAX_VALUE,则您的程序已损坏。

【讨论】:

【参考方案3】:

您最好使用java.io.Reader。该类支持skip(long n)read(char[] cbuf) 方法。但请注意,它们返回long(跳过/读取了多少字节),因此您需要循环调用这些方法。

【讨论】:

【参考方案4】:

可能最好不要使用String,而是使用StringReader

【讨论】:

嗯...我知道 StringBuffer 和 StringBuilder,但从未听说过 StringReader。请问可以展开吗?我没有看到任何子字符串方法。

以上是关于Java:具有长类型参数的 String.substring()的主要内容,如果未能解决你的问题,请参考以下文章

将具有类型参数的类作为Java中泛型方法的类型参数传递

Java:将具有不同类型的参数传递给函数

练习在Java中使用长构造函数是一个好习惯吗?

如何使用 GraalVM 从 C++ 调用具有非原始类型作为参数的 Java 入口点方法

建造者模式-具有递归类型参数的泛型类型(Effective-Java)

Firebase:类 java.util.List 具有泛型类型参数