StringBuffer如何在不创建两个对象的情况下实现append功能?

2024-03-15

这是一个面试问题。我被要求实施StringBuffer追加功能。面试后我看到了代码。但我无法理解如何通过创建单个对象来完成该操作。

我是这样想的。

String s = "orange";
s.append("apple");

这里创建了两个对象。

But

StringBuilder s = new StringBuilder("Orange");
s.append("apple");

现在这里只创建了一个对象。

Java是如何进行这个操作的呢?


首先你的问题有问题:

String s = "orange";
s.append("apple");

这里创建了两个对象

正确,创建了两个对象,字符串“orange”和字符串“apple”,在 StringBuffer/StringBuilder 内,如果我们不溢出缓冲区,则不会创建任何对象。所以这些代码行创建了 2 或 3 个对象。

StringBuilder s = new StringBuilder("Orange");
s.append("apple");

现在这里只创建了一个对象

我不知道你从哪里得到的,在这里你创建了一个 StringBuilder 对象,一个“Orange”字符串,一个“apple”字符串,总共 3 个对象,如果我们溢出 StringBuilder 缓冲区则创建 4 个对象。 (我将数组创建视为对象创建)。


我读到你的问题是,StringBuilder 如何在不创建新对象的情况下执行附加操作(当缓冲区未溢出时)?

你应该看看StringBuilder,因为它是非线程安全的实现。代码很有趣并且易于阅读。我已经添加了内嵌评论。

作为内部结构,有一个字符数组,而不是字符串。它最初的长度为 16,每次超出容量时都会增加长度。如果要附加的字符串适合 char 数组,则无需创建新对象。

StringBuilder延伸AbstractStringBuilder http://grepcode.com/snapshot/repository.grepcode.com/java/root/jdk/openjdk/6-b14/,您将在其中找到以下代码:

/**
 * The value is used for character storage.
 */
char value[];

由于并非所有数组都会在给定时间使用,因此另一个重要变量是长度:

/**  
 * The count is the number of characters used.
 */
int count;

Append 的重载有很多,但最有趣的是以下一个:

public AbstractStringBuilder append(String str) {
    if (str == null) str = "null"; //will literally append "null" in case of null
    int len = str.length(); //get the string length
    if (len == 0) return this; //if it's zero, I'm done
    int newCount = count + len; //tentative new length
    if (newCount > value.length) //would the new length fit?
        expandCapacity(newCount); //oops, no, resize my array
    str.getChars(0, len, value, count); //now it will fit, copy the chars 
    count = newCount; //update the count
    return this; //return a reference to myself to allow chaining
}

String.getChars http://download.oracle.com/javase/6/docs/api/java/lang/String.html#getChars%28int,%20int,%20char%5B%5D,%20int%29(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将此字符串中的字符复制到目标字符数组中。

所以,append 方法非常简单,唯一需要发现的魔法就是expandCapacity, 这里是:

void expandCapacity(int minimumCapacity) {
    //get the current length add one and double it
    int newCapacity = (value.length + 1) * 2; 
    if (newCapacity < 0) { //if we had an integer overflow
        newCapacity = Integer.MAX_VALUE; //just use the max positive integer
    } else if (minimumCapacity > newCapacity) { //is it enough?
        //if doubling wasn't enough, use the actual length computed
        newCapacity = minimumCapacity;
    }
    //copy the old value in the new array
    value = Arrays.copyOf(value, newCapacity); 
}

数组.copyOf http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#copyOf%28char%5B%5D,%20int%29(char[] Original, int newLength) 复制指定的数组,并用空字符截断或填充(如有必要),以便副本具有指定的长度。

在我们的例子中,填充,因为我们正在扩大长度。

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

StringBuffer如何在不创建两个对象的情况下实现append功能? 的相关文章

随机推荐

  • 相当于“Dim As String * 1”VB6 到 VB.NET

    我有一些VB6代码需要迁移到VB NET 我想询问一下这行代码 看看是否有办法在 NET中实现它 Dim strChar1 As String 1 智能感知不断告诉我声明即将结束 这就是所谓的 固定长度 字符串 VB NET 中没有完全等效
  • Java中通过Proxy发送SOAP消息

    我需要知道如何设置代理并确认它正在工作 我制作了一个如下所示的测试程序 您可以在其中指定代理地址和端口号 我在以下位置找到了地址和端口 http www freeproxylists net http www freeproxylists
  • MongoDB:查找字段名称以以下开头的对象

    查询 MongoDB 从给定的集合 参见下面的示例 中 我只需要列出包含字段的对象 其中字段名称以 need 开头 包含三个对象的集合示例 1 id 1 need some A need more 1 website id 12345678
  • 从网络加载(并显示).XIB

    我希望能够下载 通过 NSURLConnection 请求 XIB 文件 并将其呈现在视图中 我已经实现了 NSURLConnection 当然 当连接完成时 我留下了一个代表 XIB 文件的 XML 数据的 NSString 示例 只是许
  • Gradle:未指定资源类型(在“text”处,值为“@{user.name}”)。数据绑定不起作用

    我试图将适当的数据绑定功能添加到我的项目中 但由于某种原因它仍然失败 build gradle文件看起来像这样 apply plugin com android application buildscript repositories ma
  • Java 变量如何与其自身不同?

    我想知道这个问题是否可以用 Java 解决 我是该语言的新手 这是代码 class Condition you can change in the main public static void main String args int x
  • Java Swing 更新 JList

    我想知道是否有任何方法可以在用户添加或删除项目后以及用户对其进行排序后更新 Jlist 有什么方法可以编写标准化方法来根据数组或向量中的项目顺序以及当用户从 JList 所基于的数组中删除或添加对象时更新显示 谢谢 应该更新 ListMod
  • 异常处理实践顶层与每个函数

    我见过几种异常处理方法 我见过的两种最常见的模式是 在每个函数上尝试捕获 记录异常并重新抛出 在最顶层尝试捕获 如主函数 记录异常并重新抛出 如果有的话 哪一种是更好的做法 或者在什么情况下您会选择一种方法而不是另一种 这取决于您的应用程序
  • 当使用 fork() 时,getline() 会重复读取文件

    我正在开发一个简单的 shell 程序 一个命令行解释器 我想从文件中逐行读取输入 所以我使用了 getline 函数 第一次 程序工作正常 但是 当它到达文件末尾时 它没有终止 而是开始从头开始读取文件 并且无限运行 下面是 main 函
  • Python 和 sqlite3 - 导入和导出数据库

    我正在尝试编写一个脚本来导入数据库文件 我编写了导出文件的脚本 如下所示 import sqlite3 con sqlite3 connect sqlite db with open dump sql w as f for line in
  • Git:如何防止提交仅为调试目的而修改的文件?

    很多时候 我喜欢修改一些代码行以使调试更容易 但实际上我并不想提交它们 例如 我将通过注释掉某些代码行来禁用一些烦人的功能 例如广告 或者我将日志级别和过滤器设置为仅我关心的级别 或者我将强制条件为 true这样我想要运行的代码块实际上一直
  • Android 在 AlertDialog 中等待用户输入以继续

    我看到这里讨论了这个主题 但似乎不明白如何继续 In my onCreate我有代码检查它是否是应用程序的第一次运行firstRun getPref getBoolean firstRun true 如果是第一次运行该应用程序 则会显示一个
  • 具有目标 Windows 本地文件夹的 Docker 命名卷

    在 docker compose 文件中 我想创建一个命名卷 该卷将以本地驱动器为目标进行测试 对于生产 我们将使用 NFS 我创建了如下撰写文件 version 3 3 services test build volumes type v
  • SwipeRefreshLayout刷新动画不停止

    我已经实现了一个具有 SwipeRefreshLayout 作为内容视图的片段 刷新动画在 onRefresh 时触发 但即使在从服务器检索数据后将 setRefreshing 设置为 false 刷新动画也不会停止 Override pu
  • 读取 aws 凭证文件的最佳方式

    在我的 python 代码中 我需要提取 AWS 凭证 AWS SECRET ACCESS KEY 和 AWS ACCESS KEY ID 它们存储在纯文本文件中 如下所述 https docs aws amazon com sdkref
  • Google“OpenID Connect”和“使用 Google 登录”之间的区别?

    我希望我的网站的用户使用 Google 帐户进行身份验证 登录我的网站 首要的use case用户将编辑和生成内容 我们希望以安全的方式记录所有权 我们对获取用户谷歌数据不感兴趣 我们只是想要一种对用户进行身份验证的方法 谷歌搜索后 我发现
  • 是否有“std::condition_variable”的“notify_one()”队列?

    考虑第一个线程函数和全局变量 std mutex mut std condition variable officer bool firstPlayerIsReady false bool secondPlayerIsReady false
  • 是否可以在没有 IIS 的情况下使用 Windows 集成身份验证?

    我有一个 nginx 反向代理到一些节点应用程序 我们的用户都位于 Windows 域控制网络上 我知道我可以使用快递 ntlm https github com einfallstoll express ntlm or 护照 window
  • python 错误:ImportError:sys.meta_path 为 None,Python 可能会关闭

    我在pycharm中编写了一个python程序 包括FBCrawl py html login py common glovar py 在glovar py中 我定义了一个变量webdriver browser 并希望在FBCrawl py
  • StringBuffer如何在不创建两个对象的情况下实现append功能?

    这是一个面试问题 我被要求实施StringBuffer追加功能 面试后我看到了代码 但我无法理解如何通过创建单个对象来完成该操作 我是这样想的 String s orange s append apple 这里创建了两个对象 But Str