前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >StringBuilder类解析

StringBuilder类解析

作者头像
用户7886150
修改2021-02-02 11:41:01
3930
修改2021-02-02 11:41:01
举报
文章被收录于专栏:bit哲学院

参考链接: StringBuilder类

在解析StringBuilder类之前,我们先对String类做一个简单的分析。不过分析之前先想一个问题,为什么有好好的String类不用,要专用StringBuilder类呢? 

5分钟之后。。。。。。。。。。。。。。。。。。。。。。。。。。。 

1. String类简介 

1.1. String(字符串常量)概述 

String类在API中是这样描述: 

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。     字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。 

java.lang.String: 

 public final class String 

  implements java.io.Serializable, Comparable, CharSepuence 

1.2. 分析String源码 

1.2.1. String的成员变量 

    String的成员变量

    /** String的属性值 */  

    private final char value[];

    /** The offset is the first index of the storage that is used. */

    /**数组被使用的开始位置**/

    private final int offset;

    /** The count is the number of characters in the String. */

    /**String中元素的个数**/

    private final int count;

    /** Cache the hash code for the string */

   /**String类型的hash值**/

    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */

    private static final long serialVersionUID = -6849794470754667710L;

    /**

     * Class String is special cased within the Serialization Stream         Protocol.

     *

     * A String instance is written into an ObjectOutputStream according to

     * <a href="{@docRoot}/../platform/serialization/spec/output.html">

     * Object Serialization Specification, Section 6.2, "Stream Elements"</a>

     */

      private static final ObjectStreamField[] serialPersistentFields =

            new ObjectStreamField[0];

从源码看出String底层使用一个字符数组来维护的。从成员变量可以知道String类的值是final类型的,不能被改变的,所以只要一个值改变就会生成一个新的String类型对象,存储String数据也不一定从数组的第0个元素开始的,而是从offset所指的元素开始。 

1.2.2. 创建字符串的方式 

 直接赋值方式创建对象(在方法区的常量池中) String str = "hello";  //直接赋值方式

  通过构造方法创建字符串对象(在堆内存中) String str = new String("hello");  // 实例化方法

1.3. 字符串拼接问题(StringBuilder的引出) 

由于String类的对象内容不可改变,所以每当进行字符串拼接时,总是会在内存中创建一个新的对象。例如: 

public class StringDemo {

    public static void main(String[] args) {

        String value1 = "a";

        String value2 = "b";

        String value3 = "c";

        String s = value1 + value2 + value3;

        System.out.println(s);  // "abc"

    }

}

在API中对String类有这样的描述:字符串是常量,它们的值在创建后不能被更改。 

根据这句话分析我们的代码,其实总共产生了5个字符串,即"a"、"b"、"c"、"ab"和"abc"。引用变量s首先指向a对象,最终指向拼接出来的新字符串对象,即abc 。  由此可知,如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间。为了解决这一问题,可以使用java.lang.StringBuilder类。 

2. StringBuilder概述 

查阅java.lang.StringBuilder的API,StringBuilder又称为可变字符序列,它是一个类似于 String 的字符串缓冲区,通过某些方法调用可以改变该序列的长度和内容。 

原来StringBuilder是个字符串的缓冲区,即它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。 

它的内部拥有一个组用来存放字符串内容,进行字符串拼接时,直接在数组中加入新内容。StringBuilder会自动维护数组的扩容。原理如下图所示:(默认16字符空间,超过自动扩充)  2.1. 构造方法 

根据StringBuilder的API文档,常用构造方法有2个: 

public StringBuilder():构造一个空的StringBuilder容器。public StringBuilder(String str):构造一个StringBuilder容器,并将字符串添加进去。 

public class StringBuilderDemo {

    public static void main(String[] args) {

        StringBuilder sb1 = new StringBuilder();

        System.out.println(sb1); // (空白)

        // 使用带参构造

        StringBuilder sb2 = new StringBuilder("hello");

        System.out.println(sb2); // hello

    }

}

2.2. 常用方法 

StringBuilder常用的方法有2个: 

public StringBuilder append(...):添加任意类型数据的字符串形式,并返回当前对象自身。public String toString():将当前StringBuilder对象转换为String对象。 

2.2.1. append方法 

append方法具有多种重载形式,可以接收任意类型的参数。任何数据作为参数都会将对应的字符串内容添加到StringBuilder中。例如: 

public class Demo02StringBuilder {

    public static void main(String[] args) {

        //创建对象

        StringBuilder builder = new StringBuilder();

        //public StringBuilder append(任意类型)

          // append方法返回的是this,调用方法的对象builder,this==builder

        StringBuilder builder2 = builder.append("hello");

        //对比一下

        System.out.println("builder:"+builder);

        System.out.println("builder2:"+builder2);

        System.out.println(builder == builder2); //true

        // 可以添加 任何类型

        builder.append("hello");

        builder.append("world");

        builder.append(true);

        builder.append(100);

        // 在我们开发中,会遇到调用一个方法后,返回一个对象的情况。然后使用返回的对象继续调用方法。

        // 这种时候,我们就可以把代码现在一起,如append方法一样,代码如下

        //链式编程:方法返回值是一个对象,可以继续调用方法

        builder.append("hello").append("world").append(true).append(100);

        System.out.println("builder:"+builder);

    }

}

 备注:StringBuilder已经覆盖重写了Object当中的toString方法。 

2.2.2. toString方法 

通过toString方法,StringBuilder对象将会转换为不可变的String对象。如: 

public class Demo16StringBuilder {

    public static void main(String[] args) {

        // 链式创建

        StringBuilder sb = new StringBuilder("Hello").append("World").append("Java");

        // 调用方法

        String str = sb.toString();

        System.out.println(str); // HelloWorldJava

    }

}

 总结: StringBuilder和String可以相互转换: 

  String -> StringBuilder : 可以使用StringBuilder的构造方法 : 

   StringBuilder(String str) 构造一个字符串生成器,并初始化为指定的字符串内容 

  StringBuilder -> String : 可以使用StringBuilder中的toString方法 : 

   public String toString() : 将当前StringBuilder对象转换为String对象。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档