java面试题:String类

String

  1. 是不可变的常量,不可变的好处是编辑器让字符串共享,实际上只有用""声明的字符串才是共享的,存放在常量池中,使用new、subString、+等操作符生成的String字符串都不是共享的。
  2. 字符串的值比较使用的是equals(),不能使用==,==比较的是字符串地址,如果这个字符串在常量池中,那么==比较的两个引用的地址相等
  3. 直接使用“”声明的字符串都存在常量池中(实现共享)
  • String str1=”first”; 
    jvm在运行时先查找常量池中是否有该字符串,如果有则直接返回该字符串的引用给first(实现了字符串 的共享) ;否则先在常量 池中创建该字符串并返回引用。 此时只会在常量池中创建String对象,不会在堆中创建。 
  • String str2=new String(“second”); 
    该代码生成了两个String对象。因为使用了“”会现在常量池中查找是否存在second对象,没有则创建 
    否则不创建;在常量池创建完成后,由于使用了new,jvm会在堆中创建内容相同的String对象,并将引用 
    返回给str2. 
  • String str3=”what”; String str4=str3+”a nice day”; 
    运行时,+ 相当于new,所以堆中会有“what a nice day”对象;常量池中会有”what” “a nice day”两个对象,而不会有”what a nice day”对象。

字符串常量,字符串长度不可变。用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。视频里主要讲解String的内存构造,在java核心技术一书中我们知道最常用的String类方法有equals(),忽略大小写比较内容equalsIgnoreCase(),返回子串subString(),字符串拼接+,除此之外还有toCharArray()、CharAt(index)、toUpperCase()、toLowerCase() 

public class StringDemo {
	public static void main(String[] args) {
		//String--subString()
		String s = "helloWorld";
		System.out.println(s.substring(0,2));
		String s1 = s + " ILoveTheWorld";
		int age = 18;
		String s2 = s + age;
		System.out.println("拼接的结果:"+s1);
		System.out.println("拼接的结果:"+s2);
		String s3 = "helloWorld ILoveTheWorld";
		//boolean--equals()
		if(s1.equals(s2)){
			System.out.println("s1 s2内容一致");
		}
		else{
			System.out.println("s1 s2内容不一致");
		}
		if(s1.equalsIgnoreCase(s3)){
			System.out.println("s1 与s3不区分大小写的情况下内容一致");
		}
		//char[]--toCharArray()  char--charAt()
		String ss = "cscs";
		char[] c = ss.toCharArray();
		System.out.println(c);
		System.out.println(ss.charAt(0));
		//转换大小写
		String xx = ss.toUpperCase();
		System.out.println(xx);
		System.out.println(xx.toLowerCase());
		//将int、double、char、Boolean、Object等转成String 静态方法valueOf(各种类型)
		int i = 0;
		String zs = String.valueOf(i);
		//boolean--endsWith(String)
		String sss = "cs.java";
		boolean b = sss.endsWith(".java");
		System.out.println(b);
		System.out.println(sss.concat("is Student"));
		//在IO中使用的byte[] --getBytes()
		byte[] by = sss.getBytes();
		System.out.println(by);
		
	}
}

StringBuffer和StringBuilder都j继承了AbstractStringBuilder,使用了模板的设计模式,查看源码可以发现,大部分的核心数据的操作都是放在父类中进行,子类中只实现了子类额外的功能。

StringBuffer:

字符串变量(Synchronized,即线程安全)。内部采用的是可变数组,不用final修饰,默认容量是16个字符,他的变长也是由于复制造成的,所以效率比String慢。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。它的增删改等方法中修饰符由synchronized的修饰。

构造函数:StringBuffer()和StringBuffer(String)底层存储数据的Char[]数组,初始化时,该数组的长度是16。如果构造函数有新传入字符转str,则16基础上加str.length.

字符串添加:

-->先检查内部char[]数组是否需要扩容

-->如需要扩容则进行扩容,然后将原来元数据copy到新数组中。

-->再将新添加的元数据加入到新char[]数组中

StringBuilder:

字符串变量(非线程安全)底层结构和StringBuffer实现基本一样,只是没有做同步处理。

基本原则:

  • 如果要操作少量的数据用 String ;
  • 单线程操作大量数据用StringBuilder ;
  • 多线程操作大量数据,用StringBuffer。

StringBuffer的六种基本操作:

  • append()
  • length()
  • insert()
  • replace()
  • reverse()
  • toString()

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章