String存储原理
String对象中字符串主要是以 char[] (字符数组)的形式存储。当调用对象方法获取字符串长度时,直接返回数组长度。判断字符串是否为空isEmpty()时,也直接检查数组长度是否为0。
String创建实例
String s1 = "Hollis";
String s2 = new String("Hollis");
String s3 = new String("Hollis").intern();
System.out.println(s1 == s2); //输出:false
System.out.println(s1 == s3); //输出:true
String内存创建分析图
String s3 = new String("Hollis").intern();,在不调用intern情况,s3指向的是JVM在堆中创建的那个对象的引用的(如图中的s2)。但是当执行了intern方法时,s3将指向字符串常量池中的那个字符串常量。
String常用方法
//获取字符串长度
public int length()
//返回字符串中指定位置的字符;注意字符串中第一个字符索引是0,最后一个是length()-1。
public char charAt(int index)
//该方法从beginIndex位置起,从当前字符串中取出剩余的字符作为一个新的字符串返回。
public String substring(int beginIndex)
//该方法从beginIndex位置起,从当前字符串中取出到endIndex-1位置的字符作为一个新的字符串返回。
public String substring(int beginIndex, int endIndex)
//该方法是对字符串内容按字典顺序进行大小比较,通过返回的整数值指明当前字符串与参数字符串的大小关系。若当前对象比参数大则返回正整数,反之返回负整数,相等返回0。
public int compareTo(String anotherString)
//与compareTo方法相似,但忽略大小写。
public int compareToIgnore(String anotherString)
//比较当前字符串和参数字符串,在两个字符串相等的时候返回true,否则返回false。
public boolean equals(Object anotherObject)
//与equals方法相似,但忽略大小写。
public boolean equalsIgnoreCase(String anotherString)
//将参数中的字符串str连接到当前字符串的后面,效果等价于"+"。
public String concat(String str)
//返回将当前字符串中所有字符转换成小写后的新串。
public String toLowerCase()
//返回将当前字符串中所有字符转换成大写后的新串。
public String toUpperCase()
//该方法用字符replacement的内容替换当前字符串中遇到的第一个和字符串regex相匹配的子串,应将新的字符串返回。
public String replaceFirst(String regex, String replacement)
//该方法用字符replacement的内容替换当前字符串中遇到的所有和字符串regex相匹配的子串,应将新的字符串返回。
public String replaceAll(String regex, String replacement)
//截去字符串两端的空格,但对于中间的空格不处理。
String trim()
//判断参数s是否被包含在字符串中,并返回一个布尔类型的值。
contains(String str)
//将str作为分隔符进行字符串分解,分解后的字字符串在字符串数组中返回。
String[] split(String str)
String不变性概念
一旦一个string对象在内存(堆)中被创建出来,他就无法被修改。注意:String类的所有方法都没有改变字符串本身的值,都是返回了一个新的对象。如果你需要一个可修改的字符串,应该使用StringBuffer 或者 StringBuilder。否则会有大量时间浪费在垃圾回收上,因为每次试图修改都有新的string对象被创建出来。
String不变性实例
定义一个字符串
String s = "abcd";
图解
使用变量来赋值变量
String s2 = s;
图解
字符串连接
s = s.concat("ef");
图解
常见问题
Q1:String s = new String("hollis");定义了几个对象。
A1:若常量池中已经存在”hollis”,则直接引用,也就是此时只会创建一个对象,如果常量池中不存在”hollis”,则先创建后引用,也就是有两个。
Q2:如何理解String的intern方法?
A2:当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;
Q3:为什么设计成不可变?
A3:设计成不可变的主要目的是为了安全和高效。
Q4:为什么数组有length属性?
A4:首先,数组是一个容器对象,其中包含固定数量的同一类型的值。一旦数组被创建,他的长度就是固定的了。数组的长度可以作为final实例变量的长度。因此,长度可以被视为一个数组的属性。
Q5:为什么String有length()方法?
A5:String背后的数据结构是一个char数组,所以没有必要来定义一个不必要的属性(因为该属性在char数值中已经提供了)。和C不同的是,Java中char的数组并不等于字符串,虽然String的内部机制是char数组实现的。(注:C语言中,并没有String类,定义字符串通常使用char string[6] = "hollis";的形式)。
Q6:equals()和hashcode()之间关系?
A6:在判断两个对象是否相等时,不要只使用equals方法判断。还要考虑其哈希码是否相等。尤其是和hashMap等与hash相关的数据结构一起使用时。
1、如果两个对象相等,那么他们一定有相同的哈希值(hash code)。
2、如果两个对象的哈希值相等,那么这两个对象有可能相等也有可能不相等。(需要再通过equals来判断)
如果内容对你有帮助希望点赞收藏谢谢!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。