在了解这个问题的时候查了不少资料,最有帮助的是这个博文:http://swiftlet.net/archives/1694,看了一段时间,咀嚼了一段时间,写一个经过自己消化的博文,希望能帮到大家。

首先,String,StringBuffer,和StringBuilder都是对char[]的封装,而不同点在于String可以被认为是字符串常量,而StringBuffer,StringBuilder则是字符串变量。

String的成员变量如下:

 private final char value[];
private final int offset;
private final int count;

注意到char value[]是final的,代表着对象一旦被创建就不可改。我们平时常对String执行类似如下操作看起来更改字符串比较自由随意,但是其本身是不断创建新对象的过程:

String a="Hello World";
a=a+"!";
System.out.println(a);
//result: Hello World!

所以,对String执行这种经常修改字符串的操作是效率低下的。

与String不同,StringBuffer和StringBuilder都继承于AbstractStringBuilder,所以我们从AbstractStringBuilder看起

其中成员变量如下

 char value[];
int count;

首先不是final的,其次这个类引入了很多对“容量”控制的方法,很像C++中的<Vector>

例如扩容:当添加字符的长度使得char value[]超出了其本身的最大大小,需要创建一个更大的char[]并将内容复制:

 void expandCapacity(int minimumCapacity)
{
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0)
{
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity)
{
newCapacity = minimumCapacity;
}
char newValue[] = new char[newCapacity];
System.arraycopy(value, 0, newValue, 0, count);
value = newValue;
}

同样,char[]不可能所有容量都被使用,结束标识符同C一样是“\0”;

补长或者截断:

 public void setLength(int newLength)
{
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
if (newLength > value.length)
expandCapacity(newLength);
if (count < newLength)
{
for (; count < newLength; count++)
value[count] = '\0';
} else
{
count = newLength;
}
}

内存复制的方法常用的是:

public static native void arraycopy(Object src, int  srcPos, Object dest, int destPos, int length);

那么StringBuffer和StringBuilder有什么区别:先从StringBuffer和StringBuilder到String的转换看起:

 public String(StringBuffer buffer)
{
synchronized(buffer)
{
this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); }
  }
public String(StringBuilder builder)
{
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

可见,对于StringBuffer而言,处处要考虑其在多线程环境下的并发问题。也就是说,相比于StringBuilder而言,StringBuffer是线程安全的。

另外,关于String的intern方法,是将字符串常量放在一个由String类维护的常量池中。当调用intern 方法时,如果池中已经包含一个等于此String 对象的字符串(是否相等由 equals(Object)方法确定),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并且返回此String 对象的引用。例如:对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()==t.intern()才为true。

Java中的String,StringBuffer和StringBuilder的更多相关文章

  1. Android/Java 中的 String, StringBuffer, StringBuilder的区别和使用

    Android 中的 String, StringBuffer 和 StringBuilder 是移动手机开发中经常使用到的字符串类.做为基础知识是必须要理解的,这里做一些总结. A.区别 可以从以下 ...

  2. 重温java中的String,StringBuffer,StringBuilder类

    不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...

  3. 在JAVA中,String,Stringbuffer,StringBuilder 的区别

    首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String  不是线程安全的,这意味着在不同线程共享一个String ...

  4. Java中的String,StringBuilder,StringBuffer三者的区别

    最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...

  5. Java中的String,StringBuilder,StringBuffer三者的区别(转载)

    最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...

  6. 转:Java中的String,StringBuilder,StringBuffer三者的区别

    最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...

  7. [转载]Java中的String,StringBuilder,StringBuffer三者的区别

    最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...

  8. Java中的String,StringBuilder,StringBuffer的区别

    这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面. 首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > ...

  9. 【转】Java中的String,StringBuilder,StringBuffer三者的区别

    https://www.cnblogs.com/su-feng/p/6659064.html 最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及String ...

  10. Java中的String,StringBuilder,StringBuffer三者的区别(转发:https://www.cnblogs.com/su-feng/p/6659064.html)

    最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...

随机推荐

  1. 进程互斥软件实现之Lamport面包店算法

    一. 进程互斥的实现方式 1. 软件方式: 保护临界区, 自己编写代码来实现对进程的控制. Dekker算法Peterson算法Lamport算法等 2. 硬件方式: 使用特殊指令保护临界区. 开关中 ...

  2. thinkphp 模板赋值

    如果要在模板中输出变量,必须在在控制器中把变量传递给模板,系统提供了assign方法对模板变量赋值,无论何种变量类型都统一使用assign赋值. 大理石平台检定规程 $this->assign( ...

  3. Taro踩坑记录一: swiper组件pagestate定制,swiperChange中setState导致组件不能滚动。

    import Taro, { Component } from '@tarojs/taro'; import { Swiper, SwiperItem, Image, View } from '@ta ...

  4. C#多线程实现方法——线程池(Thread Pool)

    ThreadPool使用 同步机制   ThreadPool使用 需要定义waitcallback委托形式如 public delegate void WaitCallback(object stat ...

  5. 接口Interface解耦的理解

    定义一个接口 磁盘 interface Disk(){   void save(File file);   } U盘和硬盘都是磁盘,都实现这个接口 class UDisk implement Disk ...

  6. IDEA中Git的使用(多人合作)

    首先我们要简单知道github跟Git的区别.git是版本控制工具, github是一个面向开源及私有软件项目的托管平台,也是程序员交流的地方. 接下来就开始讲怎么多人一起开发. 首先我们先拥有git ...

  7. 记一次log4j日志文件小事故

    最近散仙在做公司的一个跟搜索有关的数据分析项目,主要就是统计搜索的转化率,目的主要有以下几个: (1)通过数据分析挖掘,找出搜索业务在整个平台系统里的GMV里所占份额 (2)给公司的搜索算法调优,提供 ...

  8. NoSQL 列族数据库

  9. Leetcode959. Regions Cut By Slashes由斜杠划分区域

    在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /.\ 或空格构成.这些字符会将方块划分为一些共边的区域. (请注意,反斜杠字符是转义的,因此 \ 用 &quo ...

  10. Python 编码转换与中文处理

    python 中的 unicode是让人很困惑.比较难以理解的问题. 这篇文章 写的比较好,utf-8是 unicode的一种实现方式,unicode.gbk.gb2312是编码字符集. py文件中的 ...