String那些你应该知道的事

1、String最关键的定义

首先是基本的定义,源码如下图:
String定义

定义的几个关键点

a、类是由final修饰:不可被继承也就不可以被修改,String是最多被使用的地方,是作为Java语言的基石,也是不应该被修改的。同时也便于实现字符串常量池,减少字符串的开销。

b、一个final修饰的char数组:数组保存的是String的内容。同样是被final修饰,不可修改,保证了String的内容不被修改,保证了线程安全之类的问题。

c、一个hash:上面两点保证了String的hash值不会改变,很适合用于Map的键。

2、常见方法

一个不常用但是关键的方法:compareTo()

compareTo方法
compareTo()比较的本质就是两个字符串分别从开始一个一个的比较,直到比出大小,所以平时比如数值型字符串、日期型字符串之类的比大小是可以直接比较的。

另外一个方法:join()
join方法

把数组或者集合按指定字符串拼接起来,数组、集合里面存储的必须是实现了CharSequence接口的。目前实现了它的只有三个类:String、StringBuffer、StringBuilder。具体使用如下图:
join使用

还有几个见名知意的关键方法

indexOf、lastIndexOf():字符串出现、最后出现的位置。

contains():是否包含指定字符串。

toLowerCase()、toUpperCase():字符串变小写、大写。

replace()、split():替换指定字符串、分割字符串

trim():去掉字符串两边的空格,比如" java "变成“java”

3、工具

一个专门处理String的工具类:org.apache.commons.lang3.StringUtils。它包含了基本所有对String的处理,同时防止了空指针的出现。

StringUtils.isBlank():是否为空,不管是null还是空字符串都是true。

StringUtils.isNotBlank():是否不为空,上一个方法取反。

StringUtils.isAnyBlank():同时验证多个字符串是否为空,任意为空返回true。

StringUtils.isNoneBlank():都不为空,上一个取反。

StringUtils.isAllBlank():所有都是空。

4、面试问题

问题一:==与equals 的区别
首先看下String的equals

equals方法
从代码中可以看出是先验证了==,再比较的具体内容。

基本类型的就是纯数值的比较,而对象的表示的是两个变量是否引用的同一个对象。

在Object中的equals就是用来判断的。所以如果类没有重写equals方法那么equals和相同。如果已经重写了equals方法,如果==为true,equals一定对true。equals为true,==不一定为true。

问题二:String\StringBuilder\StringBuffer的区别

String是不可变的,拼接字符串性能比较慢。StringBuilder与StringBuffer也是用来拼接字符串的,他们都比String性能更好(不会新建对象)。

StringBuffer的方法都是用synchronized修饰的,在多线程环境更加安全,但是性能也就比StringBuilder慢点。

不过多个字符串直接拼接不用去创建StringBuilder\StringBuffer再来拼接,底层已经优化。比如"a"+“b”+“c”+"d"并不会创建多个String对象,只有多次拼接,尤其是在循环中拼接字符串最好创建StringBuilder来接收。

问题三:缓存池相关的问题
如图:
常量池问题

打印结果为false,false,true。

a是new一个对象出来,和平常的对象一样。b就是JVM对String的优化了。他会先去String的常量池去查,没有就在常量池先创建一个,后面的相同字符串都指向常量池中的这个对象。c就是上一步说的JVM对String的优化了。c和b都是指向的常量池的String。

这里有一个String的方法intern(),他可以把a的值加入到常量池。不过a仍然是一个没有在常量池的对象。他只是把"abc"这个字符串加到了常量池。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!
程序员的日常笔记

发布了20 篇原创文章 · 获赞 48 · 访问量 1662

猜你喜欢

转载自blog.csdn.net/weixin_46421629/article/details/104930652