一、String,StringBuilder,StringBuffer的大概了解

大家知道String,StringBuilder,StringBuffer三个的基本应用场景。

  • String会一直创建新对象,因此频繁创建对象的场景不适合用。
  • StringBuilder则可以避免这个情况,因此频繁对字符串操作的场景使用StringBuilder比较合适。
  • 但是StringBuilder并不是线程安全的,如果要线程安全,需要使用StringBuffer。

二、为什么String会一直创建新对象?

     private final char value[];
  • String代码中,字符是存在一个 final 的 char value[]里面的。
  • 由于final指定了存储的内从是固定的,因此如果有append之类的操作的话要重新开辟新的内存。
  • 要注意的是即使 value[]是final的,它也是可以改变里面的内容的。

下面这写法是正确的。不会报错。

 final char[] ss = {'a', 'b', 'c'};
ss[0] = 'b';
ss[1] = 'c';

但是String类并没有提供这么一个接口能直接修改value数组。其中的replace是返回了一个新的String 对象。并不是在原先的数组上进行修改。

 public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */ while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}

三、StringBuilder中的主要内容

这个类继承了AbstractStringBuilder。AbstractStringBuilder里面封装了大部分内容。初始化大小为16个字符。

1、相比较String中的value,这个不是final 类型的。

char[] value;

2、newCapacity方法。

  • 将原始的capacity*2+2
  • 判断新的容量是不是合法
  • 最大容量不会超过MAX_ARRAY_SIZE。MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8.
 private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}

3、append方法

其实最终调用了System.arrayCopy将append中的String value copy到了StringBuilder 中的 value。

 public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return appendNull();
int len = sb.length();
ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);
count += len;
return this;
}

最终调用getChars方法。

 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}

四、StringBuffer中的主要内容

这个类同样继承了AbstractStringBuilder。

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

但是几乎所有的方法都加了同步。因此是线程安全的。

1、append

 @Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}

2、chartAt

 @Override
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}

其中StringBuffer里面有个 char [] toStringCache。当调用toString的时候,这个就会缓存StringBuffer的内容。当对StringBuffer有修改的时候,这个数组就会设定为null。

     private transient char[] toStringCache;

String,StringBuilder,StringBuffer区别的更多相关文章

  1. String StringBuilder StringBuffer区别

    String StringBuilder StringBuffer String类是final类,不可以被继承,且它的成员方法也是final方法,当一个字符串对象进行操作操作时,任何的改变不会影响到这 ...

  2. JAVA记录-String/StringBuilder/StringBuffer区别

  3. String, StringBuilder, StringBuffer问题

    1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...

  4. String,StringBuilder,StringBuffer的对比测试

    public class TestString { private static final int COUNT = 10000000; public static void main(String ...

  5. JDK源码分析系列---String,StringBuilder,StringBuffer

    JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...

  6. java中String StringBuilder StringBuffer比较和效率(性能)测试

    string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...

  7. 深入源码剖析String,StringBuilder,StringBuffer

    [String,StringBuffer,StringBulider] 深入源码剖析String,StringBuilder,StringBuffer [作者:高瑞林] [博客地址]http://ww ...

  8. difference among String,StringBuilder,StringBuffer

    difference among String,StringBuilder,StringBuffer String常用构造函数 String(byte[] bytes) String(byte[] b ...

  9. String Stringbuilder Stringbuffer的区别

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  10. java中string stringbuilder stringbuffer 的区别

    1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a&qu ...

随机推荐

  1. Freescale 车身控制模块(BCM) 解决方案

    中国汽车业已成为全球第一市场,标志着中国汽车产业进入了白热化竞争时代,因此,人们对汽车的操控性,安全性,易用性,舒适性,以及智能化要求也越来越高,更大的空间需求和更多的零部件因而产生了冲突,这就要求汽 ...

  2. 按奇偶排序数组 II

    题目描述 给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数. 对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数:当 A[i] 为偶数时, i 也是偶数. 你可以返回任何满足上述 ...

  3. shell中的source和直接执行sh的区别

    首先我们知道我们执行shell有这么几种方法 1. sh/bash使用其内置的命令集来执行一些命令,例如如下 sh demo.sh bash demo.sh 2. 使用./或者/$SHELLPATH/ ...

  4. redux源码解析-redux的架构

    redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且r ...

  5. Ubuntu下搜狗输入法无法输入中文

    现象:无法打出中文,但是有输入框.如下图所示情形: 解决方法 删除配置文件,重启fcitx 配置文件在~/.config下的3个文件夹里SogouPY.SogouPY.users.sogou-qimp ...

  6. poj2893 M×N puzzle

    x数码难题有解性判定: 只有必要性证明,没有充分性...... 还记得那个naive至极的八数码难题吗? 它回来了! 主要是借助逆序对这一神奇的手段: 考虑把x数码写成一排时的逆序对的奇偶性: 当你左 ...

  7. Serlect的笔记二(request 、 ersponse)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象. 下面这两个对象的基本理解: 一.HttpServletRequ ...

  8. Linux 单引号和双引号的区别

    1.单引号 单引号将其中的内容都作为了字符串来,忽略所有的命令和特殊字符,类似于一个字符串的用法 $echo 'This is a string' This is a string $echo 'ls ...

  9. 表格模型的监听 TableModelListener

    当表格内容发生改变,监听做了哪些操作,需要表格模型的监听 TableModelListener来实现. 以上一个随笔内容<高级组件——表格模型TableModel>为例,增加监听事件内容. ...

  10. STM32F407 ------ 使用定时器实现精确延时

    测试环境:主频168M #include "delay.h" void delay_init() { TIM_TimeBaseInitTypeDef TIM_TimeBaseStr ...