Java 可变字符串StringBuilder&StringBuffer 区别联系 构造器 方法
可变字符串StringBuilder&StringBuffer
-
字符串的分类:
- 不可变字符串:String。在地址不变的情况下,字符串不可改变
- 可变字符串:StringBuilder,StringBuffer。地址不变的情况下,想把“ab”变成“abcd”是可能的,直接追加即可
sb.append("cd")
-
区别与联系
- String类是不可变类,即一旦一个String对象被创建后,包含在这个对象中的字符序列是不可改变的,直至这个对象销毁。
- StringBuffer类则代表一个字符序列可变的字符串,可通过
append、insert、reverse、setChartAt、setLength
等方法改变其内容。一旦生成了最终的字符串,调用toString方法将其转变为String
- StringBuffer:JDK1.0开始 效率低 线程安全
- StringBuilder类在JDK1.5新增,与StringBuffer相似,构造方法和方法基本相同。区别在于StringBuffer是线程安全的,而StringBuilder是线程不安全的,所以性能略高。通常情况下,创建一个内容可变的字符串,应该优先考虑使用StringBuilder。将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。
- StringBuilder:JDK1.5开始 效率高 线程不安全
-
StringBuffer的主要
StringBuffer
是append
和insert
方法,它们被重载以便接受任何类型的数据。 每个都有效地将给定的数据转换为字符串,然后将该字符串的字符附加或插入到字符串缓冲区。append
方法总是在缓冲区的末尾添加这些字符;insert
方法将insert
添加到指定点。 -
StringBuilder&StringBuffer底层:非常重要的两个属性:
/**该值用于字符存储 * The value is used for character storage. */ char[] value; /**计数是使用的字符数 * The count is the number of characters used. */ int count;
-
每个字符串生成器都有一定的容量。只要字符串生成器所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区。如果内部缓冲区溢出,则此容量自动增大。 字符数组扩容,自动扩容时长度翻倍后加2。
new = old * 2 + 2
,相关源码如下:class AbstractStringBuilder private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) { value = Arrays.copyOf(value, newCapacity(minimumCapacity)); } } private int newCapacity(int minCapacity) { // overflow-conscious code 左移一位相当于乘2 int newCapacity = (value.length << 1) + 2; if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity; }
构造器
StringBuilder/StringBuffer的构造器完全相同
构造方法 | 摘要 |
---|---|
StringBuilder() | 构造一个其中不带字符的字符串生成器,初始容量为 16 个字符。 |
StringBuilder(CharSequence seq) | 构造一个字符串生成器,包含与指定的 CharSequence 相同的字符。 |
StringBuilder(int capacity) | 构造一个其中不带字符的字符串生成器,初始容量由 capacity参数指定。 |
StringBuilder(String str) | 构造一个字符串生成器,并初始化为指定的字符串内容。 |
方法
StringBuilder&StringBuffer方法基本一致,StringBuffer中个别方法使用了synchronized修饰
Modifier and Type | Method | Description |
---|---|---|
StringBuffer | appendCodePoint(int codePoint) | 将 codePoint 参数的字符串表示法附加到此序列。 |
int | capacity() | 返回当前容量。 |
char | charAt(int index) | 返回此序列中指定索引index处的 char 值。 |
int | codePointAt(int index) | 返回指定索引处的字符(Unicode代码点)。 |
int | codePointBefore(int index) | 返回指定索引之前的字符(Unicode代码点)。 |
int | codePointCount(int beginIndex, int endIndex) | 返回此序列指定文本范围内的Unicode代码点数。 |
StringBuffer | delete(int start, int end) | 删除此序列的子字符串中的字符。 |
StringBuffer | deleteCharAt(int index) | 删除 char 在这个序列中的指定位置。 |
void | ensureCapacity(int minimumCapacity) | 确保容量至少等于规定的最小值。 |
。 | ||
int | indexOf(String str) | 返回指定子字符串第一次出现的字符串内的索引。不存在返回-1。 |
int | indexOf(String str, int fromIndex) | 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。不存在返回-1。 |
int | lastIndexOf(String str) | 返回指定子字符串最右边出现的字符串内的索引。不存在返回-1。 |
int | lastIndexOf(String str, int fromIndex) | 返回指定子字符串最后一次出现的字符串中的索引。不存在返回-1。 |
int | length() | 返回长度(字符数)。 |
int | offsetByCodePoints(int index, int codePointOffset) | 返回此序列中与 index ( codePointOffset 代码点偏移的索引。 |
StringBuffer | replace(int start, int end, String str) | 用指定的String中的字符替换此序列的子字符串中的 String 。 |
StringBuffer | reverse() | 导致该字符序列被序列的相反代替。 |
void | setCharAt(int index, char ch) | 指定索引处的字符设置为 ch 。 |
void | setLength(int newLength) | 设置字符序列的长度。 |
CharSequence | subSequence(int start, int end) | 返回一个新的字符序列,该序列是该序列的子序列。 |
String | substring(int start) | 返回一个新的 String ,其中包含此字符序列中当前包含的字符的子序列。 |
String | substring(int start, int end) | 返回一个新的 String ,其中包含此序列中当前包含的字符的子序列。 |
String | toString() | 返回表示此顺序中的数据的字符串。 |
void | trimToSize() | 尝试减少用于字符序列的存储。 |
void
getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
字符从该序列复制到目标字符数组dst 。 要复制的第一个字符是索引srcBegin ; 要复制的最后一个字符在索引srcEnd-1 。 要复制的srcEnd-srcBegin总数为srcEnd-srcBegin 。 字符被复制到的子阵列dst开始于索引dstBegin且结束于 dstbegin + (srcEnd-srcBegin) - 1。
srcBegin - 以此偏移开始复制;srcEnd - 在此偏移处停止复制;dst - 将数据复制到的数组;dstBegin - 偏移到 dst 。
append
StringBuffer
append(类型 变量)
(类型 变量)
9种组合:(double
d) (float
f) (int
i) (long
lng) (String
str) (StringBuffer
sb) (boolean
b) (char
c) (char[]
str)作用:将参数的字符串表示附加到此序列
(
StringBuffer
sb)中,如果 sb 为 null,则向该序列中添加 4 个 “null” 字符。
StringBuffer
append(char[] str, int offset, int len)
将
char
数组参数的子阵列的字符串表示附加到此序列。从索引offset开始的char数组str按顺序附加到该序列的内容。 此序列的长度由的值增加len 。str - 要附加的字符,offset -要追加的第一个字符的索引,len - 要追加的 char的数量。
StringBuffer
append(CharSequence s[, int start, int end])
单参时,追加指定的CharSequence到这个序列,
如果
s
是null
,则附加四个字符"null"
。将指定的 CharSequence 的子序列附加到此序列。参数 s 的字符从索引 start 开始,按顺序附加到此序列的内容,直到(独占)索引end。 这个序列的长度增加了 end - start 的值。
令 n 为执行 append 方法之前的此字符序列的长度。 如果 k 小于 n,则该字符序列中索引 k 处的字符等于该序列中索引 k 处的字符; 否则,它等于参数 s 中索引 k+start-n 处的字符。
s - 要追加的顺序;start - 要追加的子序列的起始索引;end - 要附加的子序列的结束索引。
insert
StringBuffer
insert(int Offset, 类型 变量)
(类型 变量)
9种组合:(double
d) (float
f) (int
i) (long
lng) (String
str) (StringBuffer
sb) (boolean
b) (char
c) (char[]
str)作用:在此序列中插入参数的字符串表示形式。 参数的字符在offset的位置插入到该序列的内容中。 该序列的长度增加参数的长度。
offset
参数必须大于或等于0 ,小于或等于此序列的length 。0 <= offset <= sb.length()
(
StringBuffer
sb)中,如果 sb 为 null,则向该序列中添加 4 个 “null” 字符。
StringBuffer
insert(int index, char[] str, int offset, int len)
在此序列中插入str
数组参数的子阵列的字符串表示形式。
在此序列中插入str数组参数的子阵列的字符串表示形式。 子阵列开始在指定的offset和延伸len char秒。 子阵列的字符在index的位置被插入到该序列中。 该序列的长度增加len char s。
index - 插入子阵列的位置;str - A char数组; offset - 要插入的子阵列中的第一个 char的索引; len - 要插入的子阵列中的 char的数量。
StringBuffer
insert(int dstOffset, CharSequence s[, int start, int end])
将指定
CharSequence
的子序列插入到此序列中。如果s是null ,那么四个字符"null"被插入到该序列中。
由 start 和 end 指定的参数 s 的子序列按顺序插入到指定目标偏移处的此序列中,向上移动最初位于该位置上方的任何字符。 这个序列的长度随着end - start而增加。
该序列中索引k处的字符等于:
如果k小于dstOffset ,为此序列中索引 k 处的字符
如果k大于或等于dstOffset但小于dstOffset+end-start ,为参数 s 中索引 k+start-dstOffset 处的字符
如果k大于或等于dstOffset+end-start ,为此序列中索引 k-(end-start) 处的字符dstOffset参数必须大于或等于0 ,小于或等于此序列的length 。
dstOffset - 此序列中的偏移量;s - 要插入的序列;start - 要插入的子序列的起始索引;end - 要插入的子序列的结束索引。
实例
public class Test {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("YuZhen Feng");
//增
sb.append("nb");
System.out.println(sb); //YuZhen Fengnb
//删
sb.delete(2, 6);//删除位置在[2,6)上的字符
System.out.println(sb); //Yu Fengnb
sb.deleteCharAt(1);//删除位置在1上的字符
System.out.println(sb); //Y Fengnb
//改-->插入
sb = new StringBuffer("YuZhen Feng");
sb.insert(6, "NBPro");//在索引为6的位置上插入NBPro
System.out.println(sb); //YuZhenNBPro Feng
//改-->替换
sb = new StringBuffer("YuZhen Feng");
sb.replace(0, 6, "NBProPlusMax Xs");//将索引[0,6)位置上字符换为NBMax
System.out.println(sb); //NBProPlusMax Xs Feng
sb.setCharAt(6, '!');//将索引6处替换为 !
System.out.println(sb); //NBProP!usMax Xs Feng
//查
sb = new StringBuffer("YuZhen Feng");
for (int i = 0; i < sb.length(); i++) {
System.out.print(sb.charAt(i) + "\t"); //遍历字符串
} //Y u Z h e n F e n g
System.out.println();
//截取
String str = sb.substring(2, 6);//创建截取字符串索引得到的[2,6)的副本
System.out.println(str); //Zhen
System.out.println(sb); //YuZhen Feng
}
}