当前位置: 首页 > 知识库问答 >
问题:

Java 7字符串-子字符串复杂性

沃阳飙
2023-03-14

直到Java6,我们在String上有一个常量时间子字符串。在Java7中,为什么他们决定复制char数组——并降低线性时间复杂度——而像StringBuilder这样的东西正是为此而准备的?

共有3个答案

红甫
2023-03-14

这将对后缀数组等数据结构的复杂性产生相当大的影响。Java应该提供一些替代方法来获取原始字符串的一部分。

江子石
2023-03-14

如果你有一个长寿的短寿命的大父字符串的小子串,支持父字符串的大char[]将不符合垃圾回收机制,直到小子串移出范围。这意味着子串可以占用比人们预期的更多的内存。

Java 6方式的唯一一次表现明显更好的是,有人从一个大的父字符串中获取了一个大的子字符串,这是一种非常罕见的情况。

显然,他们认为这种变化的微小性能成本被旧方法带来的隐藏内存问题所抵消。决定性因素是问题被隐藏了,而不是有变通办法。

谭昊乾
2023-03-14

Oracle bug#4513622:(str)中讨论了他们决定的原因。保留字段的子字符串可以防止对象的GC:

当你调用字符串时。子字符串如示例中所示,未分配用于存储的新字符数组。它使用原始字符串的字符数组。因此,在子字符串的引用也可以被GC’d之前,支持原始字符串的字符数组不能被GC’d。这是一种有意的优化,以防止在常见情况下使用子字符串时分配过多。不幸的是,有问题的代码遇到了原始数组开销明显的情况。在两种情况下都很难进行优化。任何空间/大小权衡的优化通常都很复杂,而且往往是特定于平台的。

还有这个注释,注意到根据测试,曾经的优化已经变成了悲观:

很长一段时间以来,人们一直在准备和计划从java中删除偏移和计数字段。朗,弦。这两个字段允许多个字符串实例共享同一支持字符缓冲区。共享字符缓冲区对于旧的基准测试来说是一个重要的优化,但对于当前的真实代码和基准测试,实际上最好不要共享备份缓冲区。共享字符数组备份缓冲区仅“赢”,字符串使用非常频繁。子串。负面影响的情况可能包括解析器和编译器,但当前的测试表明,总体而言,这种变化是有益的。

 类似资料:
  • 问题内容: 在Java 6之前,我们在上有一个固定时间的子字符串。在Java 7中,为什么要使用复制数组并降级到线性时间复杂度? 问题答案: 在Oracle错误#4513622中讨论了为什么要做出决定:(str)保留字段的子字符串会阻止对象的GC: 如示例中那样调用String.substring时,未分配用于存储的新字符数组。它使用原始String的字符数组。因此,支持原始字符串的字符数组在子字

  • 我得到了一个复杂的JSON字符串,如下所示。 这还不完整。但这怎么读呢?

  • 我有一个逗号分层的字符串,当调用时,它返回大约60的数组大小。在特定的用例中,我只需要从数组中返回第二个值的值。例如,

  • 假设我有一个字符串,如下所示: 我想把“abcd”换成“dddd”。我曾试图做这样的事: 它不起作用。有什么建议吗? 编辑:更具体地说,我在Java工作,我试图解析超文本标记语言文档,具体地说

  • 问题内容: 基本上,我试图按其名称对表进行排序。该表相对较大,但出于示例目的,我仅发布了一列。列在下方 上面的排序是通过尝试以下操作实现的: 但是,我无法对EPA WELL 108S进行分类。我需要它在EPA WELL 108和EPA WELL 109之间移动,我尝试了许多不同的方法。 EPA之后,电台列表也会继续。 问题答案: 该解决方案比所选答案更可靠。如果站中有超过1个数字(例如“ EPA