关于StringBuffer.setLength和trimToSize

Java String专题(一)—— AbstractStringBuilder 1. 前言: 最近准备面试,正好在看关于StringBuilder和StringBuffer的源码,发现它们两个类共同继承了一个抽象类AbstractStringBuilder作为它们的父类,那也就正好从这个类开始,开始整个Java String专题的解析。 2. 关于AbstractStringBuilder类 有一点要先说明,这个类提供的所有方法都没有加锁,所以是线程不安全的。 2.1... 阅读详情

首先声明jdk-version:7u40

好了,先新建一个StringBuffer.

StringBuffer aa = new StringBuffer("12345");
下面是jdk源码:

public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
}

super() :

AbstractStringBuilder(int capacity) {
        value = new char[capacity];
}

也就是说,StringBuffer新建了容量为字符串长度+16的字符数组.

StringBuffer aa = new StringBuffer("12345");
System.out.println(aa.capacity());//21
System.out.println(aa.length());//5

下面我们调用`setLength(int newLength)`

aa.setLength(16);


再次输出

System.out.println(aa.capacity());//21
System.out.println(aa.length());//16

其中16-5多出来的被`\0`补全了.

输出:

System.out.println(aa.toString());


public void setLength(int newLength) {
        if (newLength < 0)
            throw new StringIndexOutOfBoundsException(newLength);
        ensureCapacityInternal(newLength);

        if (count < newLength) {
            for (; count < newLength; count++)
                value[count] = '\0';
        } else {
            count = newLength;
        }
}
下面这句确认是否新设置的长度,大于现有char[]的长度,大于就要扩展容量.
 ensureCapacityInternal(newLength);
    public void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > 0)
            ensureCapacityInternal(minimumCapacity);
    }

    /**
     * This method has the same contract as ensureCapacity, but is
     * never synchronized.
     */
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
    }

    /**
     * This implements the expansion semantics of ensureCapacity with no
     * size check or synchronization.
     */
    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }
至于扩容...2倍+2

如果你设置的长度,小于现有的数据长度,也就是

aa.setLength(2);
那么输出:

System.out.println(aa.capacity());//21
System.out.println(aa.length());//2
System.out.println(aa.toString());//12
容量没变,记录char[]长度的成员变量值变了,至于value[]里的值并没有消失.证据是:

我调用了:

aa.append("aa");
然后打断点...

得到下面两张图:

由此可见,不仅没消失,append只是复写了它,也就是如果可以得到count的修改权,我们能找回以前的数据...不过,反正我没得到,你办到了记得通知我.

我们继续说trimToSize,解释是它会将value[](也就是char[])的长度(容量)改成数据的长度

调用:

		StringBuffer aa = new StringBuffer("12345");
		aa.setLength(2);
		aa.append("aa");
		aa.trimToSize();
		System.out.println(aa.capacity());//4
		System.out.println(aa.length());//4

源码:

/**
     * Attempts to reduce storage used for the character sequence.
     * If the buffer is larger than necessary to hold its current sequence of
     * characters, then it may be resized to become more space efficient.
     * Calling this method may, but is not required to, affect the value
     * returned by a subsequent call to the {@link #capacity()} method.
     */
    public void trimToSize() {
        if (count < value.length) {
            value = Arrays.copyOf(value, count);
        }
    }

copyOf:

/**
     * Copies the specified array, truncating or padding with null characters (if necessary)
     * so the copy has the specified length.  For all indices that are valid
     * in both the original array and the copy, the two arrays will contain
     * identical values.  For any indices that are valid in the copy but not
     * the original, the copy will contain <tt>'\\u000'</tt>.  Such indices
     * will exist if and only if the specified length is greater than that of
     * the original array.
     *
     * @param original the array to be copied
     * @param newLength the length of the copy to be returned
     * @return a copy of the original array, truncated or padded with null characters
     *     to obtain the specified length
     * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
     * @throws NullPointerException if <tt>original</tt> is null
     * @since 1.6
     */
    public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }


也就是说,它调用了copy数组的方法,使用现在记录的长度,复制了一个基于现数组和指定长度的数组,替代了旧数组,至于旧的,我觉得它是乖乖的去等GC了,不过没有证据,因为我追到这,就停了:

/**
     * Copies an array from the specified source array, beginning at the
     * specified position, to the specified position of the destination array.
     * A subsequence of array components are copied from the source
     * array referenced by <code>src</code> to the destination array
     * referenced by <code>dest</code>. The number of components copied is
     * equal to the <code>length</code> argument. The components at
     * positions <code>srcPos</code> through
     * <code>srcPos+length-1</code> in the source array are copied into
     * positions <code>destPos</code> through
     * <code>destPos+length-1</code>, respectively, of the destination
     * array.
     * <p>
     * If the <code>src</code> and <code>dest</code> arguments refer to the
     * same array object, then the copying is performed as if the
     * components at positions <code>srcPos</code> through
     * <code>srcPos+length-1</code> were first copied to a temporary
     * array with <code>length</code> components and then the contents of
     * the temporary array were copied into positions
     * <code>destPos</code> through <code>destPos+length-1</code> of the
     * destination array.
     * <p>
     * If <code>dest</code> is <code>null</code>, then a
     * <code>NullPointerException</code> is thrown.
     * <p>
     * If <code>src</code> is <code>null</code>, then a
     * <code>NullPointerException</code> is thrown and the destination
     * array is not modified.
     * <p>
     * Otherwise, if any of the following is true, an
     * <code>ArrayStoreException</code> is thrown and the destination is
     * not modified:
     * <ul>
     * <li>The <code>src</code> argument refers to an object that is not an
     *     array.
     * <li>The <code>dest</code> argument refers to an object that is not an
     *     array.
     * <li>The <code>src</code> argument and <code>dest</code> argument refer
     *     to arrays whose component types are different primitive types.
     * <li>The <code>src</code> argument refers to an array with a primitive
     *    component type and the <code>dest</code> argument refers to an array
     *     with a reference component type.
     * <li>The <code>src</code> argument refers to an array with a reference
     *    component type and the <code>dest</code> argument refers to an array
     *     with a primitive component type.
     * </ul>
     * <p>
     * Otherwise, if any of the following is true, an
     * <code>IndexOutOfBoundsException</code> is
     * thrown and the destination is not modified:
     * <ul>
     * <li>The <code>srcPos</code> argument is negative.
     * <li>The <code>destPos</code> argument is negative.
     * <li>The <code>length</code> argument is negative.
     * <li><code>srcPos+length</code> is greater than
     *     <code>src.length</code>, the length of the source array.
     * <li><code>destPos+length</code> is greater than
     *     <code>dest.length</code>, the length of the destination array.
     * </ul>
     * <p>
     * Otherwise, if any actual component of the source array from
     * position <code>srcPos</code> through
     * <code>srcPos+length-1</code> cannot be converted to the component
     * type of the destination array by assignment conversion, an
     * <code>ArrayStoreException</code> is thrown. In this case, let
     * <b><i>k</i></b> be the smallest nonnegative integer less than
     * length such that <code>src[srcPos+</code><i>k</i><code>]</code>
     * cannot be converted to the component type of the destination
     * array; when the exception is thrown, source array components from
     * positions <code>srcPos</code> through
     * <code>srcPos+</code><i>k</i><code>-1</code>
     * will already have been copied to destination array positions
     * <code>destPos</code> through
     * <code>destPos+</code><i>k</I><code>-1</code> and no other
     * positions of the destination array will have been modified.
     * (Because of the restrictions already itemized, this
     * paragraph effectively applies only to the situation where both
     * arrays have component types that are reference types.)
     *
     * @param      src      the source array.
     * @param      srcPos   starting position in the source array.
     * @param      dest     the destination array.
     * @param      destPos  starting position in the destination data.
     * @param      length   the number of array elements to be copied.
     * @exception  IndexOutOfBoundsException  if copying would cause
     *               access of data outside array bounds.
     * @exception  ArrayStoreException  if an element in the <code>src</code>
     *               array could not be stored into the <code>dest</code> array
     *               because of a type mismatch.
     * @exception  NullPointerException if either <code>src</code> or
     *               <code>dest</code> is <code>null</code>.
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);
不过value的引用,指向已经替换成了copyOf回来的,那原数组也就是失去了引用,也就是不可达了吧,是吧?你也觉得它是等垃圾车了吧.




至于它是不是所谓的GC Roots对象,和GC Roots是否会被回收,我没有深究,如果你知道,请评论告诉我.


到此,就是我想记录的关于标题提到的两个方法,相关的事项.希望你能看完,虽然并没有什么卵用.

上下文理解的AI增强方案:AI应用架构师的架构洞察 本文将从AI应用架构师的视角,深入探讨“上下文理解”的技术本质、核心挑战,以及一套可落地的上下文增强架构方案。我们会拆解上下文理解的底层需求,分析架构设计中的关键决策,并通过具体案例展示如何构建一个能“记住过去、理解现在、预测未来”的AI系统。三个维度:上下文的内容范围(短期/中期/长期)、数据类型(文本/结构化/多模态)、技术挑战(窗口限制/信息过载/跨会话一致性);三种架构模式:分层上下文存储(热/冷数据分离)、上下文路由(按需筛选)、动态压缩(适配模型窗口);四个关键组件。 阅读详情

相关推荐

【嵌入式Linux】EC20模块多运营商自适应PPP拨号实战:从IMSI识别到网络配置

本文详细介绍了在嵌入式Linux系统中,如何基于EC20 4G模块实现多运营商自适应PPP拨号。通过解析SIM卡的IMSI识别运营商,并动态配置对应的APN和拨号参数,结合AT指令交互与健壮的pppd脚本,解决了设备跨地域部署时的网络自动连接问题,提升了物联网设备的部署效率和稳定性。

fox11的博客 903

Java高级之ArrayList中的trimToSize()方法

trimToSize()方法的源码如下: public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } }

二木成林 2148

NWD 格式转换 STL 全流程:专业方案与迪威模型网在线转换详解

在3D模型处理中,将NWD文件转换为STL格式是常见的需求,特别是在3D打印和计算机辅助制造等领域。NWD文件由Autodesk开发,主要用于建筑、工程和施工行业,包含丰富的几何图形和材质信息,但因其专有格式和大文件大小,限制了其应用范围。相比之下,STL格式广泛应用于3D打印,仅包含表面几何信息。转换NWD到STL的原因包括拓展模型应用场景和便于模型编辑。转换方法包括使用专业软件如Autodesk Navisworks配合Blender或3ds Max,或使用专门的转换工具如CADExchanger。

技术说明博主 2540

StringBuffer.setLength方法

今天发现一个方法还挺有意思,以前一直没注意,setLength方法可以直接改变该字符串为指定长度,如下 测试用例: @Test public void StringBuilder(){ String cKey = "GYAZD123456000000123"; StringBuffer sb = new StringBuffer(16); sb.append(cKey); if (sb.length() > 16).

weixin_38972910的博客 1658

全国排污许可证数据

from tkinter import * # 导入窗口控件 import tkinter.filedialog import requests from lxml import etree from tkinter import ttk from bs4 import BeautifulSoup import webbrowser # 调用浏览器打开网页 from tkinter import messagebox # 弹出提示框 from openpyxl import Workbook imp.

Newnotes的博客 3387

电力电子技术复习笔记

通常在开关过程前后加入谐振,使开关开通前电压先降到0,关断前电流先降到0,消除开关过程电压、电流的重叠,降低它们的变化率,从而大大减小甚至消除开关损耗。小信号线性化模型的原理:忽略开关频率分量和开关频率谐波分量及其边频分量,建立占空比、输入电压等的低频扰动对变换器中的电压、电流影响的模型。解:可以利用变压器的变比改变输出电压大小,避免控制过程的占空比过小或过大,提高控制精度,同时有利于减轻输出电路中电力电子器件的耐压要求。驱动电路:用于控制功率半导体器件的开关,从而控制电路的电流和电压。

Miracle Fan的博客 1万+

StringBuilder/StringBuffer setLength(0) 和 trimToSize()使用

StringBuilder/StringBuffer setLength(0) 和 trimToSize()使用

if_you_can_please_do的博客 810

uniapp 开发微信小程序请求问题 , 真机调试正常,开发工具正常,但是使用扫码预览接口都是不通的,发布到体验版也是请求失败

uniapp开发小程序体验版接口请求失败(真机可以)

weixin_60408555的博客 3954

ArrayList之trimToSize方法

看过ArrayList源码的朋友有没有看到里面有个不常用的方法: 这方法是干嘛的呢?说白了就是瘦身用的。

gzheclipse的博客 1996

AD18软件——捕捉栅格、电气栅格、可见栅格的意义及设置

本文介绍了PCB设计中的三种栅格功能:可视栅格用于辅助定位(快捷键Shift+Ctrl+G),捕捉栅格控制光标移动间距(快捷键G),电气栅格实现元件自动吸附(快捷键Shift+E)。同时提供了在Altium Designer中快速查找相同网络标号的两种实用方法:Alt+鼠标单击或双击网络。这些功能可显著提高PCB设计效率和准确性。

qq_37999850的博客 646

电源芯片MPQ3431A

MPQ3431A是一款具有宽输入范围的固定频率为450kHz的高度集成的升压转换器,其输入电压低至2.7V,采用恒定关断时间(COT)的控制拓扑,可提供快速的瞬态响应。芯片支持通过MODE管脚配置PSM(pulse-skip mode)、FCCM(forced continuous conduction mode)和USM(ultrasonic mode);还支持通过电流限制配置来达到精确的过流保护;同时芯片欠压保护(UVLO)和过温保护(OTP)。MPQ3431A采用QFN-13(3mmx4mm)封装。保

qflook的博客 1560

关于StringBuffer的setLength(0)的一个问题

今天在排查项目问题的过程中,发现了一个关于StringBuffer.setlength(0)会导致对象为NULL的问题,百思不得其解,先做记录,话不多说,上代码 //背景是这样,一个目录下有近千个文件,我的目的是读取这些文件,并且如果读取内容达到指定大小,则拆分文件,简单的说就是1000多个小文件合并成3-5个大文件。代码纯手敲,个别不符合语法的地方可以忽略 List fileObjectL...

低音钢琴的专栏 1万+

YOLO26优化:注意力魔改 | SKAttention注意力,自适应地调整其感受野大小,效果优于SENet

SKAttention输入自适应地调整其感受野大小的能力

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 250

StringBuffer用法小结

a、append方法 public StringBuffer append(boolean b) 该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接,调用该方法以后,StringBuffer对象的内容也发生改 变,例如: StringBuffer sb = new StringBuffer(“abc”); sb.append(true); 则对象sb的值将

超宇的博客 9087

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Java源码___StringBuffer类(二)

 java.lang.StringBuffer类分析摘要: &lt;1&gt;trimToSize( )方法 &lt;2&gt;setLength( int newLength )方法 &lt;3&gt;icharAt(int index)方法 &lt;4&gt;codePointAt(int index)方法 1.trimToSize( )方法  该方法会改变该类缓存区的大小,该方...

pseudonym_的博客 314

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

[源码分析]AbstractStringBuilder

[源码分析]AbstractStringBuilder Java中, AbstractStringBuilder是 StringBuilder 和 StringBuffer 的父类. 所以了解StringBuilder和StringBuffer前, 有必要先了解一下这个抽象父类. 这里附上另外两篇文章的连接: StringBuilder :http://www.cnblogs.com/no...

weixin_30570101的博客 146

StringBuilder 和 StringBuffer常用方法全解

StringBuilder提供21个核心方法,分为五类:增改操作(append/insert/delete/deleteCharAt/replace/setCharAt/setLength)、查询操作(charAt/length/indexOf/lastIndexOf/substring)、转换输出(toString/getChars)、反转操作(reverse)及容量管理(capacity/ensureCapacity/trimToSize)。其最大优势是支持链式调用且不会创建新对象,性能远优于Strin

既然你都点开这里了,那可以给我点个关注吗?可以吗?可以吗? 210

Java StringBuilder清空方式效率对比:setLength与delete、replace性能分析

字符串拼接是Java开发中的高频操作,StringBuilder作为可变字符序列的核心实现,其清空方式的选型直接影响内存分配与GC表现。底层原理上,setLength(0)复用数组、避免对象创建,而new、delete、replace则带来额外开销。在循环复用、日志拼接等场景中,正确选择清空方式可显著降低Young GC频率、提升吞吐量。本文围绕StringBuilder、清空方式、setLength、delete、replace等关键词,通过源码拆解与百万级压测,对比四种写法的效率差异,并给出真实项目中的

weixin_34392435的博客 390

StringBuffer的用法

StringBuffer的用法(线程安全的):    StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处 理时,不生成新的对象,在内存使用上要优于String类。    所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuff

偲瑾年华 617

String ,StringBuilder,StringBuffer知识总结

String ,StringBuilder,StringBuffer知识总结 String所属的包 继承关系 实现接口 java.lang继承Object接口Serializable,CharSequence,Comparable 1.String构建方式 常量 构造方法 2.String对象内存结构 字符串常用区 new堆内存对象 ==equals()区别 3.String不可变特性 长度及...

qq_45232054的博客 130

Java8源码 java.lang 包 03、AbstractStringBuilder 类

文章目录概述类的定义成员变量构造方法常用方法实现CharSequence的方法length()charAt(int)subSequencegetValuecapacityensureCapacity逻辑总结trimToSizesetLengthgetCharsappend 系列deletedeleteCharAtreplacesubstringinsert 系列indexOflastIndexOf...

github_39353936的博客 250

[java,2017-05-16] java中清空StringBuffer的方法以及耗费时间比较

java中清空StringBuffer的方法,我能想到的有4种: 1.buffer.setLength(0);设置长度为0 2.buffer.delete(0, buffer.length()); 删除0到末尾 3.buffer.replace(0, buffer.length(), ""); 替换所有内容为空字符串 4.buffer=new StringBuffer();...

weixin_34279579的博客 276

Java字符串三兄弟深度剖析:String、StringBuffer、StringBuilder源码级解读

字符串处理是Java开发中最基础也最高频的操作之一,String、StringBuilder、StringBuffer三者的选择直接影响代码性能与并发安全。String通过final与不可变字符数组实现了常量池缓存、hashCode缓存与线程安全,但代价是任何修改都会产生新对象,循环拼接性能陡降;StringBuilder基于可变数组与翻倍扩容机制,成为单线程循环拼接的最优解,字符串拼接均摊成本接近O(n);StringBuffer则在关键方法上添加synchronized锁,以少量性能换取方法级线程安全,

weixin_34235457的博客 302

用StringBuilder构建字符串

       今天接着昨天的写,关于构建字符串的一些事情。       昨天提到的用加号连接字符串,实际上效率很低,原因是每次连接字符串都要新建一个新的对象,在空间和时间上都得不偿失。StringBuilder类可以解决这个问题,它对字符串的构建操作必须在一个单线程中。如果需要在多线程中处理字符串,可以使用效率稍低的StringBuffer类。       以下大部分内容来自官方的API文档,详情...

Hippo的博客 2415

Java常用类实战指南:从String到HashMap的避坑手册

在Java开发中,语法只是入门,真正决定代码质量的是对常用类的理解与运用。String、包装类、集合框架、日期时间等高频类覆盖了日常开发90%以上的场景。掌握它们的核心原理,如String不可变性带来的线程安全与性能权衡、HashMap的hashCode与equals契约、Integer缓存与拆箱空指针隐患,能有效避免隐蔽Bug。同时,合理选用StringBuilder、ArrayList、Optional等工具,结合源码阅读与实战练习,是提升工程能力的捷径。本文从通用技术概念出发,梳理常用类的设计思想与最

weixin_31423955的博客 309

java setlength_Java StringBuffer setLength()方法

Java StringBuffer setLength()方法java.lang.StringBuffer.setLength()方法设置字符序列的长度。 序列更改为新的字符序列,其长度由参数指定。1 语法public void setLength(int newLength)2 参数newLength:这是新的长度。3 返回值此方法不返回任何值。4 示例package com.yiidian...

weixin_39947314的博客 597
上一篇: org.hibernate.util.ReflectHelper.getConstructor 空指针异常
下一篇: linux系统时间对java.Timer执行产生的影响
isCoding
博客等级 码龄14年 10粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值