String、StringBuffer、StringBuilder类
创始人
2024-05-27 04:41:47

String类

由多个字符组成的一串数据,值一旦创建不可改变

private final char value[];

一旦值改变,就会创建新的对象

String s = "abc";  //char[] c = {'a','b','c'}s+="def"; // 并不是String的值改变,而是创建了一个新的对象s+="gh";s+="aaa";
​System.out.println(s);//abcdefghaaa

String创建对象方法

  1. 简化的创建方式

    先去字符串常量池查找有没有"abc",如果没有,就在字符串常量池中创建一个对象(abc),如果字符串常量池中已有abc,那么就直接指向已有的对象即可

 String s = "abc";String s1 = "abc";System.out.println(s==s1);//trueSystem.out.println(s.equals(s1));//true
  1. new+构造方法

    凡是new出来的,在内存空间中一定是独一无二的

String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3==s4);//false
System.out.println(s3.equals(s4));//true

String、StringBuffer、StringBuilder三者的异同

String:不可变的字符序列,底层使用char[]存储,char被final修饰

StringBuffer:可变的字符序列,线程安全的,效率低,底层使用char[]存储

StringBuilder:可变的字符序列,线程不安全的,效率高,底层使用char[]存储

源码分析

String str = new String();//char[] value = new char[0]
String str1 = new String("abc");// char[] value = new char[]{'a','b','c'}
​
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16] 底层创建了一个长度为16的数组
​
sb1.append('a');//value[0] = 'a';
​
StringBuffer sb1 = new StringBuffer("abc")// char[] value = new char["abc".length()+16]

System.out.println(sb1.length());//0 这里是0的原因是:length方法返回的值并不是value.length 而是源码中的count

@Override 
public synchronized int length() { return count; }

扩容问题:如果要添加的数据底层数组装不下,那么就需要扩容底层数组

@Overridepublic synchronized StringBuffer append(Object obj) {toStringCache = null;super.append(String.valueOf(obj));// 点进父类中的append方法return this;}public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();ensureCapacityInternal(count + len);// 不会立刻添加,先判断容量是否充足str.getChars(0, len, value, count);count += len;return this;}private void ensureCapacityInternal(int minimumCapacity) {// overflow-conscious codeif (minimumCapacity - value.length > 0) {value = Arrays.copyOf(value,newCapacity(minimumCapacity));// 这里我们看到 如果我们所需容量大于数组原有的容量 就会进行数组扩容,创建一个新的容量 并将原有的数组中的元素全部复制进去}
}
​
private int newCapacity(int minCapacity) {// overflow-conscious codeint newCapacity = (value.length << 1) + 2;// 这里扩容的机制是在原数组容量的基础上扩容2倍+2if (newCapacity - minCapacity < 0) {newCapacity = minCapacity;}return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)? hugeCapacity(minCapacity): newCapacity;}

对比String、StringBuffer、StringBuilder三者的效率

从高到低排列:StringBuilder > StringBuffer > String

但是StringBuilder就一定比StringBuffer快吗?

首先我们知道StringBuilder是线程不安全的,所以我们在单线程可以使用StringBuilder更好些

StringBuffer是线程安全的,因为他的方法被synchronized修饰,所以在多线程的情况下使用StringBuffer更好些

正因如此 在我们多线程的情况下 StringBuffer的效率会比StringBuilder更快些

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...