Java字符串面试题汇总(用这一篇文章让面试官闭嘴)

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

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"));

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值