关于java String类(源码等)分析

String 类

在这里插入图片描述

  • String声明为final ,不可以被继承

  • String 实现了Serializable接口,表明字符串是可序列化的

  • String 实现了Compareble接口,表示String 可比较大小

  • String 内部定义了 final char[] value value用于存储字符串数据,表明了不可变的字符特性 ---- 1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。2.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值。3.当调用String 的 replace 方法修改指定的字符或字符串时,也需要重新指定内存区域赋值。

  • 通过字面量的方式(区别new)去给字符串赋值,此时字符串值声明在字符串常量池中,常量池中是不会存储相同内容的字符串的。

    package StringTT;

    import org.junit.Test;

    public class Stringlei {

      @Test
      public void test1(){
      	String s1 = "abc"; // 字面量的定义方式
      	String s2 = "abc";
      
      	System.out.println(s1 == s2); // 对象比较的是地址值
      	s1 = "hello";
      
      
      
      	System.out.println(s1);
      	System.out.println(s2);
      
      	System.out.println("*****************");
      	String s3 = "abc";
      	s3 += "def" ;
      	System.out.println(s3);
      }
    

    }

在这里插入图片描述

创建String对象

在这里插入图片描述
new 是在堆空间中创建

String s = new String(“abc”); 方式创建对象,在内存中创建了几个对象?两个:一个是堆空间new的结构,另一个是char[]对象常量池中的数据:“abc”

package StringTT;

import org.junit.Test;

public class StringTest2 {




	@Test
	public void test(){
	//方式一:通过字面量定义
		String s1 = "javaEE";
		String s2 = "javaEE";

	// 方式二:用new 在堆空间中创建
	
		String s3 = new String("javaEE");
		String s4 = new String("javaEE");
	
		System.out.println(s1 == s2);  // true
		System.out.println(s3 == s4);  // false
	
	}
}	

常量与常量的拼接结果在常量词中,常量与变量拼接,结果就会在堆当中

@Test
public void test1(){
	String s1 = "javaEE";
	String s2 = "hadoop";
	
	String s3 = "javaEEhadoop";
	String s4 = "javaEE" + "hadoop";
	String s5 = s1 + "hadoop";
	String s6 = "javaEE" + s2;
	String s7 = s1 + s2;
	
	System.out.println(s3 == s4); // true
	System.out.println(s3 == s5); // false
	System.out.println(s3 == s6); // false
	System.out.println(s3 == s7); // false
	System.out.println(s5 == s4); // fasle
	System.out.println(s5 == s6); // fasle
	System.out.println(s5 == s7); // fasle
	
	String s8 = s5.intern(); // 得到的是在常量池
	System.out.println(s8 == s3); // true 
}

String 方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

String 和 char[] 的转换

  • String 转 char[] 用 String.toCharArray()方法

  • char[] 转 String 调用String 的构造器

    package StringTT;

    import org.junit.Test;

    public class StringTest1 {
    // String 和 byte的转换
    @Test
    public void test123(){
    String str1 = “abc123”;
    char[] charArray = str1.toCharArray();
    for (int i = 0;i < 100; i++){
    System.out.println(charArray[i]);
    }
    }

      @Test
      public void test2(){
      	char[] ch1 = new char[]{'h','e','l','l','o'};
      	String str2 = new String(ch1);
      	System.out.println(str2);
      }
    

    }

String 和 byte[] 的转换

有中文的话就转不了一个数字了
编码 :字符串 --> 字节 (看得懂 -->看不懂)String 转 byte[] 用String的getBytes()方法
解码:字节 – > 字符串(看不懂的二进制 – > 看得懂)byte[] --> String
解码过程中,必须与编码所使用的字符集一致

package StringTT;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

import org.junit.Test;

public class StringTest1 {
	// String  和 byte的转换
	@Test
	public void test123(){
		String str1 = "abc123";
		char[] charArray = str1.toCharArray();
		for (int i = 0;i < str1.length(); i++){
			System.out.println(charArray[i]);
		}
	}


	@Test
	public void test2(){
		char[] ch1 = new char[]{'h','e','l','l','o'};
		String str2 = new String(ch1);
		System.out.println(str2);
	}


	@Test
	public void test3() throws UnsupportedEncodingException{
		String str1 = "abc123中国";
		byte[] b1 = str1.getBytes(); // 使用默认的字符集进行转换
		System.out.println(Arrays.toString(b1)); //输出
	
		byte[] b2 = str1.getBytes("gbk"); //使用gbk字符集进行编码
		System.out.println(Arrays.toString(b2));
	
		//解码 byte[] --> String
		String s1 = new String(b1); // 默认的字符集进行解码
		System.out.println(s1);
	}
}

StringBuffer 、StringBuilder、String 异同

  • String 不可变的字符序列,底层用char[]进行存储
  • StringBuffer 可变的字符序列,线程安全的,效率偏低,底层用char[]进行存储
  • StringBuilder 可变的字符序列,JDK5.0新增,线程不安全,效率高,底层用char[]进行存储

源码分析

String str = new String();//char[] value = new char[0];
String str = new String(“abc”); // char[] value = new char[]{‘a’,‘b’,‘c’};

StringBuffer str = new StringBuffer();//char[] value = new char[16]; 底层创建了一个长度是16的字符数组

StringBuffer str1 = new StringBuffer(“abc”); // char[] value = new char(“abc”.length + 16) 创建了长度为19的字符数组

问题1:打印str1的长度是多少呢?还是3
问题2:如果要添加的数据,底层数据盛不下了,那就需要扩容底层的数组。默认情况下,扩容为原来容量的两倍+2,同时将原有数组的元素复制到新数组中

指导意义:开发中建议使用StringBuffer(int capacity) 或 StringBuilder(int capacity) ,就看需不需要考虑安全

package StringTT;

import org.junit.Test;

public class StringBufferBuiderTest {
	@Test
	public void test(){
	StringBuffer sb1 = new StringBuffer("abc");
	sb1.setCharAt(0, 'm');
	System.out.println(sb1);

	String s1 = "abc";
	s1.replace('a','m');
	System.out.println(s1); //s1不变
	}
}

在这里插入图片描述
public String substring – 返回一个start 开始 end索引结束的左闭右开区间的子字符串

在这里插入图片描述

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

JDK8.0之前 日期和时间API

@Test
public void test(){
	long time = System.currentTimeMillis();
	System.out.println(time);  //1970/1/1 到我们现在的时间差 毫秒数,通常叫一个时间戳
}

猜你喜欢

转载自blog.csdn.net/abc1234564546/article/details/127842411