1.String是基本类型吗?
- String不是基本类型,是引用类型。基本类型只有八种:int,long,float,double,boolean,char,byte,short,每一种对应着相应的包装器。
- String是不可变类
2.创建String对象的方式有哪些?区别是什么?
- 使用new关键字创建:
1) 如果字符串池中没有该字符串常量池,那么就分别在字符串常量池和堆中创建对象,并将堆中的对象的地址返回
2)如果字符串常量池中有该字符,那么就仅在堆中创建对象,并将堆中的对象地址返回 - 使用双引号创建:
1)此时会在字符串常量池中寻找是否有相应字符串,如果有则返回该地址
2)如果没有则在字符串常量池中创建对象返回地址
具体可以看我的这篇博客:String和newString的区别
3.String, StringBuffer,StringBuilder的区别?
- 由于String是不可变类,所以是线程安全的,但是由于不可修改,所以每次修改都需要创建新的对象,比较浪费资源,所以引入StringBuffer,StringBuilder类,这两个类都是可变的
- StringBuffer和StringBuilder类都是可变类,但是StringBuffer是线程安全的,而StringBuilder是线程不安全的。所以在多线程的环境下可以使用StringBuffer,但是效率和速度没有StringBuilder高
- StringBuffer实现线程安全的方法是在内部方法上用synchronized关键字修饰,其实就是加锁。
4.String是不可变的有什么好处?
- 因为不可变,所以是线程安全的,可以多线程使用
- 由于不可变,所以可以用于密码存储
- 可以很好的作为hashmap中key值存储等
5.如何判断两个String是否相等?(==和equals的区别)
- ==判断的是字符串的地址
- equals方法是Object中的方法,在重写之前也是判断地址,但是重写之后就是判断内容是否相等了
- 所以判断的时候一定要明白对比字符串的地址是从字符串常量池中拿的还是从堆中取的
不懂的还是可以看我的这两篇博客:String和new String的区别,
==和equals的区别
String s1 = "aaa";
String s2 = "aaa";
System.out.println(s1 == s2);//true
System.out.println(s1.equals(s2));//true
String s3 = "bbb";
String s4 = new String("bbb");
System.out.println(s3 == s4);//false
System.out.println(s3.equals(s4));//true
String s5 = s4;
System.out.println(s5 == s4);//true
System.out.println(s5.equals(s4));//true
6.为什么我们在使用HashMap的时候总是用String做key?
- 因为String是不可变的,这就保证了安全性。
- 另一方面String很好的重写了Hashcode方法和equals方法
7.String的intern()方法?
- 当intern()方法被调用,如果字符串池中含有一个字符串和当前调用方法的字符串eqauls相等,那么就会返回池中的字符串。如果池中没有的话,则首先将当前字符串加入到池中,然后返回引用
- 解释:
1)首先要明白这个方法的返回值是一个字符串,并且保证这个字符串来自于字符串池中
2)当调用方法的对象是堆中的对象时,那么就会将这个堆中的对象加到池中,返回池中的对象地址! - 所以其实只要明白了每次创建对象的地址是来自于堆还是字符串池,这些就很好理解
8.字符串相加的原理?
String str1 = "a";
String str2 = "b";
String str3 = "ab";
String str4 = str1 + str2;
String str5 = "a" + "b";
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
问题:为什么str3和str4的地址不同?按理来说都是在字符串池中的对象
- String str5 = “a” + “b”; 当字符串相加的部分中全部都是常量时,那么就会直接进入字符串池中进行操作,所以我们生成的str5对象地址就在字符串池中
- String str4 = str1 + str2;当字符串相加部分中有变量,那么就会用StringBulider的方式来添加,那么返回的地址就是堆中的地址!
- 一个在堆中,一个在字符串池中,当然会是false
9.写一个方法来判断一个String是否是回文(顺读和倒读都一样的词)?
- 如果是用Stringbuild或StringBuffer,可以用resver方法反转字符串,然后调用equals方法判断是否相同
- 如果不让使用任何API,就直接进行首尾遍历字符串即可
10.如何让一个字符串变成小写或大写形式?
- 使用toUpperCase 和 toLowerCase 方法让一个字符串变为 大写或小写。
11.如何比较两个字符串?
-
String内部实现了Comparable接口,有两个比较方法:compareTo(String anotherString) 和compareToIgnoreCase(String str)。
-
compareTo(String anotherString)
与传入的anotherString字符串进行比较,如果小于传入的字符串返回负数,如果大于则返回证书。当两个字符串值相等时,返回0.此时eqauls方法会返回true。 -
equalsIgnoreCase(String str)
该方法与compareTo方法类似,区别只是内部利用了Character.toUpperCase等方法进行了大小写转换后进行比较。
12.如何将String转换为char,反过来呢?
- String不可能转化为char,但是可以转化为char数组
- 调用toCharArray() 方法
String str = "hello world";
char[] chars = str.toCharArray();
System.out.println(chars.length);
13.如何将String转换为byte array,反过来呢?
- 使用String的getBytes()方法将String转成byte数组,使用String的构造方法 new String(byte[] arr) 将byte数据转为String。
14.给几行代码,判断字符串输出是fasle还是true?
- 其实这个就是自己判断一下对象的地址来自于内存还是字符串池,只有深入理解了,就可以懂了!