Java字符串面试题

1、什么是String,它是什么数据类型?
答:String是定义在java.lang包下的一个类,它不是基本数据类型。
String是不可变的,JWM使用字符串池来储存所有的字符串对象。
2、创建String对象的不同方式有哪些?
答:两种方式。
一种是通过new很关键字来创建。使用这种方式时,JWM创建字符串对象但不存储在字符串池中,我们可以调用intern()方法将该字符串对象存储在字符串池中,如果该字符串池已经有了同样值得字符串,则返回引用。
另一种是使用双引号来直接创建。使用这种方式时。JVM去字符串找有么有相同值得字符串,如果有,则返回找到的字符串引用。否则创建一个新的字符串对象,并·存储在字符串池中。
例如:

String str=new String("abc");
String str1="abc";

3、写一个方法来判断一个String是否是回文(顺读和倒读都一样的词)?
答:String类中并没有提供翻转方法供我们使用,但StringBuffer和StringBuilder有reverse方法。

private static boolen isPalindrome(String str){
	if(str==null){
		return false;
	}
	StringBuilder strBuilder=new StringBuilder(str);
	srtBuilder.reverse();
	return strBuilder.toString().equals(str);
}

不使用reverse方法实现

private static boolean isPalindromeString(String str){
	if(str==null)
		return null;
	int length=str.length();
	System.out.println(length/2);
	for(int i=0;i<length/2;i++){
		if(str.charAt(i)!=str.charAt(length-i-1))
			return false;
	}
	return true;
}

4、如何让一个字符串变成小写或大写形式?
答:toUpperCase和toLowerCase方法
5、如何比较两个字符串?
答:String内部实现了Comparable接口,有两个比较方法:compareTo(String anotherString)和compareToIgnoreCase(String str)。
compareTo(String anotherString)与传入的anotherString字符串进行比较,如果小于传入的字符串返回负数,如果大于则返回正数。当两个字符串值想等时,返回0此时equals方法会返回true。
equalsIgnoreCase(String str)该方法与compareTo方法类似,区别只是内部利用了Character.toUpperCase等方法进行了大小转换后进行比较。
6、如何将String转换为char,反过来呢?
答:String是一系列字符,所以我们无法转换成单一的char但是可以调用toCharArray()方法将字符串转换成字符数组。

	String str="Java interview";
	//string to char array;
	char[] chars=str.toCharArray();
	system.out.println(chars.length);

7、如何将String转换为byte array,反过来呢?
答:使用String的getBytes()方法将String转换成byte数组,使用String的构造方法new String(byte[] arr)将byte数据转为String。

public class StringToByteArray{
	public static void main(String[] args){
			String str="PANKAJ";
			byte[] byteArr=str.getBytes();
			//print the byte[] elements
			System.out.println("String to byte array:"+Array.toString(byteArr))
	}
	public static void main(String[] args)
	{
		byte[] byteArray={'P','A','N','k','A','J'};
		byte[] byteArray={80,65,78,75,65,74};
		String str=new String(byteArray);
		Srting str1=new String(byteArray1);
		System.out.println(str);
		System.out.println(str1);
	}
}

8、浅谈一下String, StringBuffer,StringBuilder的区别?
答:String是不可变类,每当我们对String进行操作的时候,总会创建新的字符串。操作String和耗费资源,所以java提供了两个工具类来操作String——StringBuffer和StringBuilder。
StringBuilder和StringBuffer是可变类,StringBuffer是线程安全的,StringBuilder则不是线程安全的。所以在多线程对同一字符串进行操作的时候,我们选择StringBuffer。在不需要处理多线程的情况下,StringBuilder的效率比StringBuffer高。
9、String是不可变的有什么好处?
答:由于String是不可变类,所以在多线程中使用是安全的,我们不需要做其他任何同步操作。
String是不可变的,其值也是不可变的,所以用来存储数据密码很安全。
因为java字符串不可变,可以在java运行时节省大量堆空间。因为不同的字符串变量可以引用池中的相同的字符串。如果字符串是可变的话,任何一个变量的值改变,就会映射到其他变量,那么字符串池也就没有什么意义了。
10、如何分割一个String?
答:public String[] split(String regex):
根据传入的正则字符串进行分割,注意,如果最后一位刚好有传入的字符,则返回的数组不会有空字符串。

	String s="abcada"
	System.out.println(Arrays.toString(s.split("a"));
	//以上代码输出结果为[,bc,,d].
	public String[] split(String regex,int limit):
	//限制分割结果数组中有几个字符串。传入2,则结果分割后数组长度为2。
	String s="Y,Kunming,Yunnan";
	String[] data=s.split(",".2);
	System.out.println("Name=",data[0]);//Y
	System.out.println("Address=",data[1]);//Kunming,Yunnan
	//实际上第一个方法调用了第二个方法,只不过不限制返回的数组长度了
	public String[] split(String regex)
	{
		return split(regex,0);
	}

11、如何判断两个String是否相等?
答:有两种方式判断字符串是否相等,使用“= = ”或者使用equals方法。当使用 “= =”操作符时,不仅比较字符串的值还比较引用的内存的值。大多相互情况下,我们只需要判断值是否相等,此时用equals方法即可。
还有一个用equalsIgnoreCase可以用来忽略大小写进行比较。

	String s1="abc";
	String s2="abc"
	String s3=new String("abc");
	System.out.println("s1 == s2 ? "+(s1==s2));//true
	System.out.println("s1 == s3 ? "+(s1==s3));//false
	System.out.println("s1 equals s3 ? "+s1.equals(s3));//true

12、什么是字符串池?
答:顾名思义,字符串常量池就是用来存储字符串的,它存在于java对内存中。
下图解释了字符串池在java堆空间中如何存在以及当我们使用不用方式创建字符串时情况。
Java字符串面试题_第1张图片

public class StringPool{
	public static void main(String[] args){
		String s1="cat";
		String s2="cat";
		String s3=new String("cat");
		System.out.println("s1==s2:",(s1==s2));
		System.out.println("s1==s3:",(s1==s3))
	}
}

结果如下:
s1= =s2:true
s1= =s3:false
以上代码会创建1或2个字符串。如果字符串池中已经有一个字符串“cat”,那么就会自动创建一个“cat”字符串。如果字符串常量池中没有“cat”,那么首先会在字符串池中创建,然后才在堆内存中创建,这种情况下就会创建2个对象了。
13、String的intern()方法
答:当intern()方法被调用,如果字符串池中已经有一个字符串和当前调用方法的字符串equals相等,那么就会返回池中的字符串。如果池中没有的话,则首先将当前字符串加入到池中,然后返回引用。
14、String是线程安全的吗?
答:String是不可变量,一旦创建了String对象,我们就无法改变他的值,因此,它的线程是安全的,可以安全的用于多线程环境中。
15、为什么我们在使用HashMap的时候总是用String做key?
答:因为字符串是不可变的,当创建字符串的时候,他的hashcode被缓存下来,不需要再次计算。因为HashMap内部实现是通过key的hashcode来确定value的存储位置,所以相比于其他对象更快。这也就是为什么我们平时使用String作为HashMatp对象。
16、String编程题
1、下面的代码输出什么
String s1 = new String(“abc”);
String s2 = new String(“abc”);
System.out.println(s1 == s2);
输出:false
2、下面的代码输出什么
String s1 = “abc”;
StringBuffer s2 = new StringBuffer(s1);
System.out.println(s1.equals(s2));
输出:false,s2不是String类型,是StringBuffer类,s1用了String的equals方法进行了类型判断
3、下面的代码输出什么
String s1 = “abc”;
String s2 = new String(“abc”);
s2.intern();
System.out.println(s1 ==s2);
输出:false
4、下面的代码将创建几个字符串对象。
String s1 = new String(“Hello”);
String s2 = new String(“Hello”);
答案是 2个对象.

17,说说String/StringBuffer/StringBuilder它们之间的区别?为什么要引入其它两种字符串处理类?
答:目的是提高字符串连接效率。在大部分情况下,字符串拼接速度为:StringBuilder>StringBuffer>String.
String是不可变的,因此每次对其操作改变变量值,其实都是生成一个新的对象,然后将变量引用指向新的对象,因此速度慢。
StringBuffer则不同,对其操作即直接操作对象指向的引用,无需产生新的对象,速度很快;它的线程是安全的,在维护多线程的同步上也会损耗一些性能。
StringBuilder是JDK5之后新增的,其用法与StringBuffer一致,但它的线程是不安全的,在单线程中最佳,因为其不需要维护线程安全,因此也是最快的。
String 字符串常量(线程安全)。StringBuffer 字符串变(线程安全)。StringBuilder 字符串变量(非线程安全)。String是不可变的,StringBuffer/StringBuilder 是可变的;String/StringBuffer是线程安全的,StringBuilder是非线程安全的。
18、这里引入一个新的问题,了解String.intern()方法吗?
String.intern()查找常量池中是否有相同的unicode字符串常量,如果有则返回其引用,如果没有,则在常量池中增加一个unicode等于str的字符串并返回它的引用。因此在用String进行字符串拼接时,会产生很多临时变量。建议多使用StringBuffer/StringBuilder。
19、String/StringBuffer/StringBuilder都分别存放在什么地方?
String是存放在常量池中,在编译期间已经被确定了。new String()不是字符串常量,他有自己的地址空间,放在堆空间,而其他两个都存放在堆空间中。

你可能感兴趣的:(其他)