字符串驻留和文字字符串声明的搜索成本

2024-03-31

两个问题。

  1. 当我们声明文字字符串时,我们会在堆的字符串池中查找是否有相同的字符串。这也是实习吗(班级的方法实习生String)?

  2. 在我看来,每个文字字符串声明都需要进行二分搜索或其他操作,因此它至少需要花费log(n) when n是池中现有字符串的数量。而且如果池里的字符串很多的话,可能成本会很高。 (也许是搜索成本和内存的权衡?)从这个角度来看,声明 mant 文字字符串可能是危险的。这种搜索成本有多重要,以及为什么 java 以这种方式设计(声明文字字符串时搜索池)。

以下是我所提到的了解背景。


The JavaDoc 为java.lang.String class http://download.oracle.com/javase/6/docs/api/java/lang/String.html状态:

字符串是恒定的;它们的值在创建后就无法更改。字符串缓冲区支持可变字符串。因为 String 对象是不可变的,所以它们可以共享。

http://www.janeg.ca/scjp/lang/strLiteral.html http://www.janeg.ca/scjp/lang/strLiteral.html评论:

换句话说,因为编译器知道字符串的原始值一旦创建就无法更改,因此它可以安全地使用现有数据并避免重复项造成内存混乱。


您将编译时间复杂性与运行时复杂性混淆了。

当加载类时,是的,它会进行搜索以查看每个文字是否已经存在(尽管我想它会使用哈希图进行 O(1) 查找而不是您的建议)。

当代码运行时,它会引用内存中的字符串,因此与非文字相比没有额外的成本。

所以是的,文字被拘留了。根据 String 的 Javadoc,

字符串池最初是空的,由 String 类私有维护。

您可以调用intern()在字符串上将其添加到该池中。从逻辑上看,如果a.equals(b) then a.intern() == b.intern(), since .intern()保证从唯一的池中返回。

Example:

class InternTest {
    // assuming InternTest is the only class, internPool.size = 0
    String x = "ABC"; // interned at class load, internPool.size = 1
    String y = "DEF"; // interned at class load, internPool.size = 2
    String z = "ABC"; // interned at class load, but match found - size = 2 still

    void foo() {
        // random int is just a mechanism to get something that I know won't
        // be interned at loadtime - could have loaded from file or database too
        int i = (new java.util.Random()).nextInt(1000) + 100;
        int j = i;
        String s = String.valueOf(i); // not yet interned, size = 2 still
        String t = String.valueOf(j); // not yet interned, size = 2 still

        String sIntern = s.intern(); // manually interned, size = 3 now
        String tIntern = t.intern(); // manually interned, match found, size = 3 still

        System.out.println("equals: " + (s.equals(t))); // should be true
        System.out.println("== raw: " + (s == t)); // should be false, different variables
        System.out.println("== int: " + (sIntern == tIntern)); // should be true, from unique pool

       System.out.println("x and z: " + (x == z)); // should be true, interned at class load
    }

    public static void main(String[] args) {
        (new InternTest()).foo();
    }

}

运行结果:

C:\Documents and Settings\glowcoder\My Documents>java InternTest
equals: true
== raw: false
== int: true
x and z: true

我应该指出,这个假设永远不会成立。 Java语言本身有很多String在我们之前会被实习的String我们有机会重见天日。然而,假设所有内容都是按顺序加载的,如果您只考虑被实习生的字符串增量,并假设与现有实习生没有冲突(我们都知道实习生可能很挑剔并且充满戏剧性,对吧?snicker)那么这些数字确实表示字符串池大小的增量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字符串驻留和文字字符串声明的搜索成本 的相关文章

随机推荐

  • 如何在 Puppeteer 中选择 iframe 元素内的元素

    由于 ESPN 不提供 API 因此我尝试使用 Puppeteer 来抓取有关我的 Fantasy Football League 的数据 但是 由于登录表单嵌套在 iframe 元素中 我很难尝试使用 puppeteer 登录 我已经去了
  • Next12 中带有 Prisma 适配器的 NextAuth 凭证提供程序不执行任何操作

    我已经设置了我的Nextjs Next12 with NextAuth 凭证提供者并使用棱镜适配器将用户会话保留在数据库中 我跟着这个文档 https next auth js org adapters prisma来自 NextAuth
  • 求解混合互补模型时出错

    直接使用 PATH 求解器 我无法解决下面提出的问题 最初的问题来源于https prod sandia gov techlib noauth access control cgi 2015 155584 pdf https prod sa
  • 以良好的质量和内存效率缩小资源中的位图

    我想缩小 500x500px 资源以始终适合由屏幕宽度确定的特定尺寸 目前我使用 Android 开发者网站 高效加载大位图 http developer android com training displaying bitmaps lo
  • on_message() 和 @bot.command 问题

    当我有on message 在我的代码中 它会停止所有其他的 bot command来自工作的命令 我尝试过await bot process commands message 但这也行不通 这是我的代码 bot event command
  • SQL Server - PIVOT - 两列转换为行

    我在一个专栏中看到了很多关于 PIVOT 的问题 每个问题都比其他问题更复杂 但是 我找不到我需要的任何内容 老实说 我什至不知道pivot在这种情况下是否能帮助我 假设我的源表中有这些数据 SELECT 1 as RowId Random
  • 混淆 .fmt 行为与嵌套列表

    The docs https docs raku org routine fmt比如说fmt 返回一个字符串 其中列表中的每个元素都已根据以下格式进行格式化 format 第一个参数 并且每个元素由 separator 第二个论点 根据该描
  • EmguCV (OpenCV) ORBDetector 仅发现不良匹配

    Problem 所以总的来说 我对计算机视觉还很陌生 我目前正在尝试通过分析 2 个图像来计算单应性 我想使用单应性来校正 1 个图像的视角以匹配另一个图像 但我得到的比赛却很糟糕而且错误 所以我所做的单应性扭曲完全关闭了 当前状态 我正在
  • 在“data.table”中使用动态列名

    我想计算 data table 中每一列的平均值 并按另一列分组 我的问题与另外两个问题类似 one https stackoverflow com questions 12391950 variably selecting assigni
  • 创建 IEnumerable.Find()

    我想写 IEnumerable
  • Hibernate Envers:检索具有集合属性的实体的正确修订

    我有两个经过审计的实体 A 和 B 实体 A 拥有实体 B 的集合 注释为一对多关系 将 A 的新实例插入数据库时 A 和 B 的所有行都处于同一修订版 假设为修订版 1 然后 A 上有一个更新 仅影响实体 B 的实例 因此 更新后 实体
  • WiX RemoveRegistryKey 元素的行为不符合广告

    卸载时我似乎无法删除注册表项 请注意 这不是重复this https stackoverflow com questions 3317281 wix doesnt remove registrykey on uninstall问题 因为我不
  • scikit-learn - 将管道预测转换为原始值/规模

    我创建了一个管道 如下所示 使用Keras Scikit Learn API https keras io scikit learn api estimators estimators append standardize Standard
  • 如何使用 jquery 禁用列表框中的多重选择?或者JavaScript?

    我的页面中有一个列表框 td 我需要禁止从列表框中选择多个项目吗 我正在做一些事情 比如选择一个项目 然后单击 删除 按钮 我的页面会从列表框中删除一项 但是如果我选择多个项目 则会抛出一条错误消息 任何人都可以帮我解决如何停用或禁用列表框
  • 熊猫重新索引日期索引按组重新访问

    之前已经问过这个问题 这里已经提出了一个可行的解决方案Pandas 在 Groupby 中重新索引日期 https stackoverflow com questions 32275540 pandas reindex dates in g
  • GraphViz:未使用新安装程序设置 Windows PATH,从 R 调用时出现问题

    在 R 库中 我使用dot程序 来自 GraphViz 来生成一些图形 通常为 png 格式 dot是一个通常的可执行文件 我通过systemR 命令 到目前为止 一切都运行良好 因为 GraphViz 安装程序正在添加dot到 PATH
  • 以 Vararg 作为第一个参数的 Kotlin 方法

    Note我查看了以下问题 答案来解决问题 但没有任何运气 从 Kotlin 调用 Java Varargs 方法 https stackoverflow com questions 36626152 call java varargs me
  • 具有特定数字的浮点精度

    以下值给出了错误的精度 仅通过特定数字即可观察到这一点 可能是浮动表示问题 但想知道具体原因 String m 154572 49 154 572 49 Float f Float parseFloat m System out print
  • 了解 Go 中的 http handlerfunc 包装器技术

    我看到一个马特 赖尔撰写的文章 https medium com statuscode how i write go http services after seven years 37c208122831关于如何使用服务器类型和包装器类型
  • 字符串驻留和文字字符串声明的搜索成本

    两个问题 当我们声明文字字符串时 我们会在堆的字符串池中查找是否有相同的字符串 这也是实习吗 班级的方法实习生String 在我看来 每个文字字符串声明都需要进行二分搜索或其他操作 因此它至少需要花费log n when n是池中现有字符串