Java字符串面试题汇总(用这一篇文章堵住面试官的嘴)
1.String 字符串介绍
String属于引用数据类型,由于被final修饰,所以String是不可变的,JVM使用字符串池来存储所有的字符串对象。
2 创建String的不同方式有哪些
2.1 通过new关键字
使用这种方式时, 每次new都会生成一个新的对象 (JVM创建字符串对象但不存储于字符串池。new相同内容的字符串对象会重新生成一个对象, 我们可以调用intern()方法将该字符串对象存储在字符串池,如果字符串池已经有了同样值的字符串,则返回引用。

2.2 双引号创建
使用这种方式时,JVM去字符串池找有没有值(内容)相等的字符串,如果有,则返回找到的字符串引用。否则创建一个新的字符串对象并存储在字符串池。

3 equals和==区别
==比较基本数据类型时,比较的是内容;比较引用数据类型String时,比较的是指向堆内存地址是否一样
eauals比较String的内容
4 String和StringBuffer和StringBuilder的区别
String str="a";
for(int i=1:i<10000;i++){
str+="a";
}
StringBuffer str1=new StringBuffer("a");
for(int i=1:i<10000;i++){
str.append("a");
}
StringBuilder str1=new StringBuilder("a");
for(int i=1:i<10000;i++){
str.append("a");
}片
String是不可变类,作的时候,总每当我们对String进行操是会创建新的字符串。操作String很耗资源,所以Java提供了两个工具类来操作String - StringBuffer和StringBuilder。
StringBuffer和StringBuilder是可变类,StringBuffer是线程安全的,StringBuilder则不是线程安全的。所以在多线程对同一个字符串操作的时候,我们应该选择用StringBuffer。由于不需要处理多线程的情况,StringBuilder的效率比StringBuffer高。
5 如何将String转换为byte,反过来呢
5.1 将String转换为byte
String str = "PANKAJ"; byte[] byteArr = str.getBytes();
5.2 将byte转换成String
byte[] byteArray = { 'P', 'A', 'N', 'K', 'A', 'J' };
byte[] byteArray1 = { 80, 65, 78, 75, 65, 74 };
String str = new String(byteArray);
String str1 = new String(byteArray1);
6 如何将String转换为char,反过来呢
6.1 String转换为char
String word="cnjsk vdjsk";
char[] c = word.toCharArray();
6.2 char转换为String
char data[] = {'s', 'g', 'k'};
String str = new String(data);
7 如何使字符串变成大写或者小写
toUpperCase()转大写
ToLowerCase()转小写
String str = "aBv";
//转大写
String upperCase = str.toUpperCase();
System.out.println(upperCase);
//转小写
String lowerCase = str.toLowerCase();
System.out.println(lowerCase);
8 写一个方法来判断一个String是否是回文(顺读和倒读都一样的词)
回文就是正反都一样的词,如果需要判断是否是回文,只需要比较正反是否相等即可。String类并没有提供反转方法供我们使用,但StringBuffer和StringBuilder有reverse方法。
private static boolean isPalindrome(String str) {
if (str == null)
return false;
StringBuilder strBuilder = new StringBuilder(str);
strBuilder.reverse();
return strBuilder.toString().equals(str);
}
9 String是不可变的有什么好处?
10.1 由于String是不可变类,所以在多线程中使用是安全的,我们不需要做任何其他同步操作。
10.2 String是不可变的,它的值也不能被改变,所以用来存储数据密码很安全。
10.3 因为java字符串是不可变的,可以在java运行时节省大量java堆空间。因为不同的字符串变量可以引用池中的相同的字符串。如果字符串是可变得话,任何一个变量的值改变,就会反射到其他变量,那字符串池也就没有任何意义了。
10 什么是字符串池?
顾名思义,字符串常量池就是用来存储字符串的。它存在于Java 堆内存。
下图解释了字符串池在java堆空间如何存在以及当我们使用不同方式创建字符串时的情况。

11 下面代码创建了几个对象
String str = new String("Cat");
答案:一个或者两个
原因:先判断字符串常量池里面有没有Cat字符串对象,如果有,就不会在常量池里面创建Cat对象,但是会在堆内存里面创建一个Cat对象,并将对象地址返回给str变量,这种情况创建一个对象;
如果常量字符串没有,就会现在常量池里面创建Cat字符串,然后再在堆内存里面创建Cat字符串对象,这种情况会创建两个对象
12 String的intern()方法
当intern()方法被调用,将字符串放到字符串常量池里面,如果字符串池中含有一个字符串和当前调用方法的字符串eqauls相等,那么就会返回池中的字符串。如果池中没有的话,则首先将当前字符串加入到池中,然后返回引用。
13 说一下以下代码输出结果
案例一:
String s = new String("abc");
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s == s1);
System.out.println(s == s2);
System.out.println(s1 == s2);
第一句执行后内存中有两个对象,而不是一个。一个由new String(“abc”)中的”abc”在字符串常量池生成一个值为”abc”的对象;第二个由new在堆里产生一个值为”abc”的对象,该对象完全是String Pool里的”abc”的一个拷贝。变量s最后指向堆中产生的”abc”对象;
第二句执行时,变量s1先去String Pool找是否有值为”abc”的对象,很显然在上一步中java已经在String Pool里生成一个”abc”对象了,所以s1直接指向String Pool中的这个”abc”;
第三句中又有一个new,首先会去字符串常量池中找“abc”,若能找到则直接获取地址,不再创建新的常量。在java中凡遇到new时,都会在堆里产生一个新的对象。因此,该句执行后堆里又多了一个”abc”对象,这与执行第一句后生成的”abc”是两个不同的对象,s2最后指向这个新生成的对象。
因此,执行后面的打印语句的结果是三个false 。
案例二:
String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel" + "lo"); //true
System.out.println(hello == "hel" + lo); //false
前三句在String Pool里分别产生“hello”、“hel”、“lo”三个常量字符串对象。
“hel”+”lo” 这是两个字符串拼接成一个”hello”字符串对象,拼接后会在String pool看有没有hello字符串对象,如果有,则返回已有对象的地址,没有的话,就在String pool创建一个hello字符串对象
“hel”+lo 这相当于修改lo字符串对象,由于字符串是不可变的数据类型,所以会在字符串堆内存里面创建一个新的字符串对象
注意:修改字符串对象会在堆内存里面创建一个字符串对象
14 equals ()使用时的注意事项
常量和确定值要放在equals的左边,如果把不确定的值放在左边,不确定值为null时,就会报错。
String str = null;
System.out.println(str.equals("123"));

本文详细介绍了Java中字符串的相关知识,包括字符串的不可变性、创建方式、equals与==的区别、String、StringBuffer与StringBuilder的区别、字符串转换以及回文判断等面试常考问题。强调了字符串池的作用和String的intern()方法的应用。
796

被折叠的 条评论
为什么被折叠?



