前端小记 前端小记
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
  • 学习笔记

    • 《Vue》踩坑笔记
    • TypeScript学习笔记
    • 小程序笔记
    • JavaScript设计模式笔记
  • 工具
  • CentOS
  • Java
  • Docker
  • Linux
  • Maven
  • MySQL
  • 其他
  • 技术文档
  • GitHub部署及推送
  • Nodejs
  • 博客搭建
  • Fullpage全屏轮播插件
  • svn
  • 学习
  • 系统重装
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

sweetheart

前端小记
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
  • 学习笔记

    • 《Vue》踩坑笔记
    • TypeScript学习笔记
    • 小程序笔记
    • JavaScript设计模式笔记
  • 工具
  • CentOS
  • Java
  • Docker
  • Linux
  • Maven
  • MySQL
  • 其他
  • 技术文档
  • GitHub部署及推送
  • Nodejs
  • 博客搭建
  • Fullpage全屏轮播插件
  • svn
  • 学习
  • 系统重装
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • centos

  • java

    • Java中日志框架的使用
    • idea上传代码到github的3种方式
    • idea快捷键失效问题解决
    • 解决Eclipse中spring的xml文件下方不显示NameSpaces标签的问题
    • Java集合
    • Java中比较对象大小的两种实现方式
    • String、StringBuffer、StringBuilder的对比
      • 概述
      • 三者部分源码
        • String 部分源码
        • StringBuffer 部分源码
        • StringBuilder 部分源码
      • 1.是否可变?
      • 2.线程是否安全?
      • 3.执行效率
      • 4.初始化方式
      • 5.是否实现了 hashCode 和 equals 方法
      • 6.使用场景
    • Java泛型的使用
    • Java反射机制
    • Lambda表达式
  • docker

  • Linux

  • maven

  • MySQL

  • 其他

  • 后端
  • java
sweetheart
2019-07-16
目录

String、StringBuffer、StringBuilder的对比

# String、StringBuffer、StringBuilder 的对比

# 概述

Java 提供了 String、StringBuffer 和 StringBuilder 类来封装字符串,并提供了一系列操作字符串对象的方法。

三者的共同点是都用来封装字符串、都实现了 CharSequence 接口、底层都使用 char[]存储。但是它们之间也存在不同点。

# 三者部分源码

# String 部分源码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{

    private final char value[];

    private int hash; // Default to 0

    private static final long serialVersionUID = -6849794470754667710L;

    private static final ObjectStreamField[] serialPersistentFields =
     new ObjectStreamField[0];

      public String()
      {
       this.value = "".value;
      }
      public String(String original)
      {
         this.value = original.value;
         this.hash = original.hash;
      }
      public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
      }
      public boolean equals(Object anObject)
      {
        if (this == anObject) {
          return true;
        }
        if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
         char v1[] = value;
         char v2[] = anotherString.value;
         int i = 0;
         while (n-- != 0) {
          if (v1[i] != v2[i])
            return false;
              i++;
             }
             return true;
           }
       }
       return false;
      }
       public int hashCode() {
         int h = hash;
          if (h == 0 && value.length > 0) {
          char val[] = value;

       for (int i = 0; i < value.length; i++) {
         h = 31 * h + val[i];
        }
          hash = h;
         }
         return h;
       }
        public int indexOf(int ch) {
          return indexOf(ch, 0);
        }
    ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# StringBuffer 部分源码

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    private transient char[] toStringCache;

    static final long serialVersionUID = 3388685877147921107L;

    public StringBuffer() {
        super(16);
    }
    public StringBuffer(int capacity) {
        super(capacity);
    }

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

    public StringBuffer(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }
  ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# StringBuilder 部分源码

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    static final long serialVersionUID = 4383685877147921099L;

    public StringBuilder() {
        super(16);
    }

    public StringBuilder(int capacity) {
        super(capacity);
    }

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

    public StringBuilder(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }
   ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 1.是否可变?

String 是被 final 修饰的,是不可变的字符序列,是字符串常量,即使调用 String 的concat 方法,也只是把字符串拼接起来,把拼接后的 String 的值赋给新创建的对象。

StringBuffer 和 StringBuilder 是可变的字符序列,是字符串变量,类的对象能够被多次的修改,并且不产生新的未使用对象。
1
2
3

# 2.线程是否安全?

String中的对象是不可变的,是被final修饰的,是字符串常量,是线程安全的。

StringBuffer对象在缓冲区被多个线程使用时,它的中的方法大都使用了synchronized 关键字进行修饰,加了同步锁,所以是线程安全的。

StringBuilder是jdk5.0新增的,在使用时没有被synchronized 关键字修饰,不能保证线程安全,可能会出现一些操作错误。

AbstractStringBuilder是StringBuilder和StringBuffer的公共父类,定义了一些字符串的基本操作,它们的用法基本相同。

多线程情况下建议使用StringBuffer,单线程建议使用速度较快的StringBuilder。
1
2
3
4
5
6
7
8
9

# 3.执行效率

StringBuilder最高,StringBuffer次之,String最低。
1

# 4.初始化方式

创建String对象时,可以利用构造方法String str = new String("haha")的方式来对其进行初始化,也可以直接用赋值的方式String s = "haha"来进行初始化。而StringBuffer只能使用构造方法StringBuffer sb = new StringBuffer("hahaha")的方式来进行初始化。
1

# 5.是否实现了 hashCode 和 equals 方法

String实现了equals和hashCode方法,new String("haha").equals(new String("haha"))的结果为true;

而StringBuffer没有实现equals和hashCode方法,new StringBuffer("heihei").equals(new StringBuffer("heihei"))的结果为false。
1
2
3

# 6.使用场景

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。 append方法与直接使用+串联相比,减少常量池的浪费。

一般而言,如果要操作少量的数据时,优先使用String类;如果是在单线程下操作大量数据,优先使用StringBuilder类;如果是在多线程下操作大量的数据,优先使用StringBuilder类。
1
2
3
4
5
完善页面 (opens new window)
上次更新: 2024-11-28 17:23:47
Java中比较对象大小的两种实现方式
Java泛型的使用

← Java中比较对象大小的两种实现方式 Java泛型的使用→

最近更新
01
git常用操作手册
12-26
02
常用的前端工具库
12-19
03
前端构建工具
12-19
更多文章>
前端小记 版权所有 | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式