你听说过吗?CharSequence家族之String三剑客[Sting-StringBuffer-StringBuilder]的进制奇缘!

Posted 四原色

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你听说过吗?CharSequence家族之String三剑客[Sting-StringBuffer-StringBuilder]的进制奇缘!相关的知识,希望对你有一定的参考价值。

你听说过吗?CharSequence家族之String三剑客的[Sting-StringBuffer-StringBuilder]的进制奇缘!


1.String

1.1源码分析

1.1.1 String对象的实例化
	//直接使用字符串字面量进行赋值
	String str = "四原色";
	
	//使用intern()方法实例化String对象:
	//创建对象前会从字符串常量池中查询当前字符串是否存在,
	//如果存在,就直接返回当前字符串;
	//如果不存在就会将当前字符串放入常量池中,之后再返回。
	String str_inner = new String("四原色").intern();
	
	//无参构造,构造一个空字符串对象,值为null,不是"null"
	String str_noprimary = new String();
	
	//通过字符串数组构造
	char []chars = ['a','b','c'];
	String str_chars = new String(chars);
	
	//通过指定长度字符数组构造,从指定索引开始的指定长度
	String str_charsAsSize = new String(chars,0,1);
	
	//使用字符串字面量实例化字符串对象
	String str_chars_value = new String("四原色");
	
	//通过字节数组实例化
	byte []bytes = [1,2,3,4,5];
	String str_bytes = new String(bytes);
	
	//通过指定长度字节数组构造,从指定索引开始的指定长度
	String str_bytes_value = new String(bytes,2,3);
	    
	String str_bytes_sharsetStart = new String(bytes,String charsetName);
	
	String str_bytes_sub_sharsetStart = new String(byte[] bytes,
		int offset,
		int lentth,
		String charsetName);
	
	String str_stringBuffer = new String(StringBuffer buffer);
	
	String str_stringBuilder = new String(StringBuilder builder);
1.1.2常用方法
	String str = "四原色";
	
	//获取字符串长度
	int len = str.length(); 
	
	//字符串连接
	str.concat("666");
	str = "abc" + "cde";
	
	//从一个字符组截取一个字符
	char starChar = str.charAt(0);
	
	//获取子串,从start下标到最后一个。
	String subStar = str.subString(1);
	
	//获取子串,从start下标到最后一个,到end结束,不包括end。
	String subStarEnd = str.subString(02);
	
	//到一个字符数组
	char []chars = str.toCharArray(); 
	
	//到一个字节数组
	byte []bytes = str.getBytes();
	
	//指定的字符集,到一个字节数组
	String charsetName = "666";
	byte []bytesAsCharset = str.getByates(charsetName); 
	
	//放置到指定字符数组,
	//把str的第0个索引值开始到第1个索引值插入到新字符数组0索引位置
	char []target = ['1','a','c'];
	str.getChars(0,1,target,0);
	
	//将字符串中的出现的字母转为大写
	"abc".toUpperCase();
	
	//将字符串中的出现的字母转为小写
	"ABC".toLowerCase(); 
	    
	//去掉空格
	str.trim() ;
	
	//字符替换,将字符串str中的字符'6'替换为'5'
	String new_str = str.replace('6','5');
	
	//字符串替换,使用正则表达式regex替换指定格式字符串为新值replacement
	String regex = "[a-z]";
	String replacement = "A";
	String new_strAll = str.replaceAll(regex,replacement);
1.1.3 String源码分析
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence 
    {...}
  1. String类被final关键字修饰,不能被继承,它的成员方法都默认为final方法;字符串一旦创建就不能再修改,当对String进行变更时将在字符串常量池中产生新的字符串,即批量对字符串的处理是产生的内存消耗是非常大的.

  2. String类实现了Serializable、CharSequence、 Comparable接口.

  3. String实例的值是通过字符数组实现字符串存储的.

1.1.4 编译器对String的优化
  1. 对+字符串连接的优化:

    使用"+"连接字符串对象时,会创建一个StringBuilder()对象,即JVM会隐式创建StringBuilder对象,并调用append()方法将数据拼接,最后调用toString()方法返回拼接好的字符串。

	String str = "四原色"+ "666";
	
	String str = new StringBuilder("四原色").append("666").toString();
  1. 对编译器确定的字符串常量进行优化:

    当"+“两端均为编译期确定的字符串常量时,编译器会进行相应的优化,直接将两个字符串常量拼接好,此时字符串常量池中将存在的字符串常量是“四原色666”,而非"四原色"和"666”.

	System.out.println("四原色" + "666");
	
	System.out.println("四原色666");
  1. 使用final修饰的字符串常量的优化:

    对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的 “四原色” + str 和 “四原色” +“666” 效果是一样的。此时字符串常量池中存在的字符串常量有:“666”,"四原色666"故结果为true。

	String str1 = "四原色666"; 
	final String str = "666"; 
	String str2 = "四原色" + str;  
	System.out.println((str1 == str2));

1.2内存模型

1.2.1 String的堆栈存储模型
	String str = "四原色666";
	String str1 = "四原色666";
	String str2 = "四原色";
	String str3 = new String("666");
	System.out.println(str == str1);//true
	System.out.println(str1 == str3);//false

​ 1. 常量池中不存在两个相同的对象,所以str和str1都是指向JVM字符串常量池中的"四原色666"。new关键字一定会产生一个对象,并且这个对象存储在堆中。

​ 2. String str3 = new String(“333”)产生了两个对象:保存在栈中的str3和保存堆中的String对象。

​ 3. 当执行String str = "四原色666"时,JVM首先会去字符串常量池中检查是否存在"四原色666"对象,如果不存在,则在字符串常量池中创建"四原色666"对象,并将"四原色666"对象的地址返回给str1;如果存在,则不创建任何对象,直接将字符串常量池中"四原色666"对象的地址返回给str1。


2.StringBuffer

2.1实例化StringBuffer

	/*源码*/
		public StringBuffer() {
	        super(16);
	    }
	
	    public StringBuffer(int capacity) {
	        super(capacity);
	    }
	
	    public StringBuffer(String str) {
	        super(str.length() + 16);
	        append(str);
	    }

	//分析这几个构造器可以知道,
	//SringBuffer初始字符空间为16.
	//也可以通过构造方法设置这个初始空间。
	//如果再追加字符串是,字符空间超出了当前字符空间大小,
	//则调用this(seq.length() + 16),即字符空间大小每次增加时都增加16.
	
	//无参构造,默认为16个字符的空间
	StringBuffer sbf1 = StringBuffer();
	
	//指定字符长度构造StringBuffer对象
	StringBuffer sbf2 = StringBuffer(18);
	
	//指定字符串构造StringBuffer对象
	StringBuffer sbf3 = StringBuffer("四原色666");

2.2 常用方法

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

​ StringBuffer类跟String类一样定义成final形式,主要是为了“效率”和“安全性”的考虑,若StringBuffer 被继承,由于它的高使用率,可能会降低它的性能。StringBuffer实现了Serializable接口和CharSequence接口,继承了AbstractStringBuilder类。

  1. 获取StringBuffer字符长度和字符的空间大小
/*源码*/
    @Override    
    public synchronized int length() {return count;}    
    @Override    
    public synchronized int capacity() {return value.length;}
    //length()获取的是StringBuffer对象值得长度;
    //capacity()获取的是StringBuffer对象字符的空间;
    //    如:
    StringBuffer sb = new StringBuffer();
    int len = sb.length();
    int cap = sb.capacity();
    //len = 0;
    //cap = 16;
  1. 设置字符空间大小
	/*源码*/
	@Override    
	public synchronized void setLength(int newLength) {
	        toStringCache = null;
	        super.setLength(newLength);    
	 }
	 StringBuffer sb = new StringBuffer();
	 //默认字符空间大小为16sb.setLength(10);
	 //设置字符空间大小为10
  1. 获取字符,设置字符
 	/*源码
 	 	@Override   
 	 	 public synchronized char charAt(int index) {        
 	 	 	if ((index < 0) || (index >= count))            
 	 	 		throw new StringIndexOutOfBoundsException(index);        
 	 	 	return value[index];    
 	 	 }    
 	 	 @Override    
 	 	 public synchronized void setCharAt(int index, char ch) {       
 	 	  	if ((index < 0) || (index >= count))            
 	 	  		throw new StringIndexOutOfBoundsException(index);        
 	 	  	toStringCache = null;       
 	 	    value[index] = ch;    
 	 	}*/
 	 	
 	 	StringBuffer sb = new StringBuffer("四原色yyds");
 	 	char fistChar = sb.charAt(0);
	 	//获取索引为0的字符sb.setCharAt(sb.length()-1,'!');
	 	//设置最后一个字符为!
  1. 向字符串中追加字符/字符串
       //源码
	@Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this;
    }
    @Override
    synchronized StringBuffer append(AbstractStringBuilder asb) {
        toStringCache = null;
        super.append(asb);
        return this;
    }
    @Override
    public synchronized StringBuffer append(CharSequence s) {
        toStringCache = null;
        super.append(s);
        return this;
    }
    @Override
    public synchronized StringBuffer append(CharSequence s, int start, int end){
        toStringCache = null;
        super.append(s, start, end);
        return this;
    }
    @Override
    public synchronized StringBuffer append(char[] str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    @Override
    public synchronized StringBuffer append(char[] str, int offset, int len) {
        toStringCache = null;
        super.append(str, offset, len);
        return this;
    }
    @Override
    public synchronized StringBuffer append(boolean b) {
        toStringCache = null;
        super.append(b);
        return this;
    }
    @Override
    public synchronized StringBuffer append(char c) {
        toStringCache = null;
        super.append(c);
        return this;
    }
    @Override
    public synchronized StringBuffer append(int i) {
        toStringCache = null;
        super.append(i);
        return this;
    }
    @Override
    public synchronized StringBuffer append(long lng) {
        toStringCache = null;
        super.append(lng);
        return this;
    }
    @Override
    public synchronized StringBuffer append(float f) {
        toStringCache = null;
        super.append(f);
        return this;
    }
    @Override
    public synchronized StringBuffer append(double d) {
        toStringCache = null;
        super.append(d);
        return this;
    }
  1. 删除字符/字符串
    /*源码
    @Override    
    public synchronized StringBuffer delete(int start, int end) {
            toStringCache = null;        
            super.delete(start, end);        
            return this;    
    }   
    @Override    
    public synchronized StringBuffer deleteCharAt(int index) {        
    	toStringCache = null;        
    	super.deleteCharAt(index);        
    	return this;    
   }*/
  1. 字符串的替换
 //*源码
 @Override    
 public synchronized StringBuffer replace(int start, int end, String str) {
         toStringCache = null;        
         super.replace(start, end, str);        
         return this;    
 }
  1. 获取子串
    //*源码
    @Override    
    public synchronized String substring(int start) {
            return substring(start, count);
    }    
    @Override    
    public synchronized CharSequence subSequence(int start, int end) {
            return super.substring(start, end);    
    }    
    @Override    
    public synchronized String substring(int start, int end) {
            return super.substring(start, end);    
    }
  1. 插入字符/字符串
	//*源码@Override
    public synchronized StringBuffer insert(int index, char[] str, int offset,
                                            int len)
    {
        toStringCache = null;
        super.insert(index, str, offset, len);
        return this;
    }
    @Override
    public synchronized StringBuffer insert(int offset, Object obj) {
        toStringCache = null;
        super.insert(offset, String.valueOf(obj));
        return this;
    }
    @Override
    public synchronized StringBuffer insert(int offset, String str) {
        toStringCache = null;
        super.insert(offset, str);
        return this;
    }
    @Override
    public synchronized StringBuffer insert(int offset, char[] str) {
        toStringCache = null;
        super.insert(offset, str);
        return this;
    }
    @Override
    public StringBuffer insert(int dstOffset, CharSequence s) {
        super.insert(dstOffset, s);
        return this;
    }
    @Override
    public synchronized StringBuffer insert(int dstOffset, CharSequence s,
            int start, int end)
    {
        toStringCache = null;
        super.insert(dstOffset, s, start, end);
        return this;
    }
    @Override
    public  StringBuffer insert(int offset, boolean b) {
       super.insert(offset, b);
        return this;
    }
    @Override
    public synchronized StringBuffer insert(int offset, char c) {
        toStringCache = null;
        super.insert(offset, c)以上是关于你听说过吗?CharSequence家族之String三剑客[Sting-StringBuffer-StringBuilder]的进制奇缘!的主要内容,如果未能解决你的问题,请参考以下文章

你听说过吗?CharSequence家族之String三剑客[Sting-StringBuffer-StringBuilder]的进制奇缘!

你听说过吗?CharSequence家族之String三剑客[Sting-StringBuffer-StringBuilder]的进制奇缘!

付费上班,你听说过吗?

付费上班,你听说过吗?

0002JDK源码分析之Appendable接口家族

阿里算法天才盖坤解读阿里深度学习实践,CTR预估MLR模型兴趣分布网络这些名词你都听说过吗?