文章目录
String类
构造方法
- String(String original):创建一个字符串对象
- String(char[] value):把数组数据封装成字符串对象
- String(char[] value, int index, int count):把数组一部分封装成字符串对象。
常用方法
判断
- boolean equals(Object obj):判断2个字符串是否相等。
- boolean equalsIgnoreCase(String s):忽略大小写判断2个字符串是否相同。
- boolean startsWith(String str):判断字符串是否以str开头。
- boolean endsWith(String str):判断字符串是否以str结尾。
- boolean contains(String str):判断是否包含str字符串
获取
- int length():获取字符串长度
- char charAt(int index):获取指定索引处的字符
- int indexOf(String str):获取str第一次出现的索引
- String substring(int start):从start开始截取字符串
- String substring(int start,int end):从start开始到end截取字符串
转换
- char[] toCharArray() 把字符串转成字符数组。
- String toLowerCase() 把字符串全小写。
- String toUpperCase() 把字符串全大写。
其他
- String trim() 把两边空格去掉。
- String[] split(String str) 分割字符串。
StringBuilder与StringBuffer
并对其做了追加和插入操作。这些操作修改了 str 对象的值,而没有创建新的对象,这就是 StringBuilder 和 String 最大的区别。
StringBuilder s=new StringBuilder("hello");
s.append("world");//追加方法
s.insert(5," "); //插入方法
s.reverse();//翻转字符串
StringBuilder与StringBuffer的区别
StringBuilder 和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
String常量池
为什么需要常量池
- 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能
- JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化,为字符串开辟一个字符串常量池,类似于缓存区。
- 创建字符串常量时,首先坚持字符串常量池是否存在该字符串,存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中。
为什么String设计成不可变的
-
字符串常量池的需要。字符串常量池的诞生是为了提升效率和减少内存分配。可以说我们编程有百分之八十的时间在处理字符串,而处理的字符串中有很大概率会出现重复的情况。正因为String的不可变性,常量池很容易被管理和优化。
-
安全性考虑。正因为使用字符串的场景如此之多,所以设计成不可变可以有效的防止字符串被有意或者无意的篡改。从java源码中String的设计中我们不难发现,该类被final修饰,同时所有的属性都被final修饰,在源码中也未暴露任何成员变量的修改方法。(当然如果我们想,通过反射或者Unsafe直接操作内存的手段也可以实现对所谓不可变String的修改)。
-
作为HashMap、HashTable等hash型数据key的必要。因为不可变的设计,jvm底层很容易在缓存String对象的时候缓存其hashcode,这样在执行效率上会大大提升。
经典面试题
-
new String(“abc”)创建几个对象?
简单的回答是一个或者两个,如果是常量区有值为"abc"的值,则只在堆中创建一个对象;如果常量区没有则会在常量区创建"abc",此处的常量区是方法区的运行时常量池(也称为动态常量区)。
new都会在堆中创建对象。直接String s = "xxx"不会涉及堆,只在常量区检查是否有该常量。 -
intern()方法
在调用”ab”.intern()方法的时候会返回”ab”,但是这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用。