【问题标题】:Why is there an offset in the Java String implementation?为什么 Java String 实现中有偏移量?
【发布时间】:2013-11-11 03:41:48
【问题描述】:

我一直在研究实现,但我不明白为什么会有偏移量。我认为这很重要。

我正在学习 Sedgewick 教授的算法课程,现在我们正在讨论字符串。在讲座中,他简要讨论了 String 的实现,但他没有解释为什么会有偏移量(注意,如果讲座不在线,我肯定会问)。

似乎当人们在实现中创建一个字符串时,它被赋予了一个偏移量,我似乎无法理解为什么需要一个偏移量。即使出于子字符串的目的,我也不完全理解为什么会有偏移量。例如,显然如果你创建一个字符串"David",它实际上是['X', 'X', 'D', 'a', 'v', 'i', 'd', 'X'],或者类似的东西,它被'X's 所抵消。这是为什么呢?

【问题讨论】:

  • 您在看哪个 Java 版本? Oracle 的 JDK 7 实现不再使用偏移字段。
  • 在 Java 7 更新 4 之前,字符串可以指向另一个字符串的一部分,因此它需要知道该部分的开始位置。
  • 好问题!我一直认为偏移的原因是您可以执行splitsubstring 等等,而无需复制支持数组。但我没有证据表明这是决定以这种方式实施的实际理由。
  • 我在问题中添加了更多内容。 @DavidWallace,我不确定抵消也会有什么帮助。
  • 好吧,我的意思是,如果你这样做"David asked a good question".split(" ");,那么生成的"David", "asked", "a", "good""question" 可以共享与原始String 相同的字符数组,但只是有不同偏移量和长度,以便它们显示数组的不同部分。这样一来,角色本身就不需要被复制了。

标签: java string implementation


【解决方案1】:

这在字符串需要从另一个更长的字符串派生的情况下很有用,类似于 substring()。

在这种情况下,可以使用相同的(不可变的)后备数组,同时调整偏移量和长度,以节省内存并优化性能。

JDK7 中不再是这种情况。

【讨论】:

  • 所以本质上,你是说如果我有例如['X', 'X', 'D', 'a', 'v', 'i', 'd', 'X'],我可以使用这个完全相同的数组,但是偏移量会改变,所以每当我执行任何事情时,它都会简单地执行它在这个数组的一个子集上?例如,如果偏移量为 2,而我想要 'vid',则偏移量将变为 4,基于此我可以在保留空间的同时进行所有必要的计算?
  • @David 是的,没错。这就是允许子字符串如此容易计算的原因:它使用具有不同偏移量的支持数组;使用字符串时,评估只会改变(例如在System.out.println()中)。
  • @David 实际上,我误读了您的评论。这并不完全正确。创建字符串时(假设没有优化技巧)它将只是['D', 'a', 'v', 'i', 'd']。当您开始调用子字符串、拆分等时,您会看到使用了此支持数组的部分内容。
【解决方案2】:

偏移量通常作为优化存在。例如,在字符数组相关项中,可以多次使用同一个字符数组,从数组中构造多个String。这是因为您将使用具有不同偏移量和长度的相同数组。

这是一个非常有效的优化,因为它避免了仅仅为了让您希望从零索引处开始的字符而构建新字符数组的需要。例如,在读入一个字节块(可能来自套接字)之后,您可以将其分块为字符串大小的消息,而无需进行不必要的字节复制。

【讨论】:

    猜你喜欢
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    相关资源
    最近更新 更多