String
String
Java中通过String类来创建和操作字符串数据。
1.String实例化
1.直接赋值
String str1="Hello Word!";
2.通过构造函数创建对象
String str2=new String("Hello Word!");
2.String两种实例化方法的区别
首先,我们来看一段代码:
String str1="Hello Word!";
String str2=new String("Hello Word!");
System.out.println(str1==str2);
System.out.println(str1.equals(str2));
结果是false和true;由此可见,str1和str2指向的是不同的内存地址,但是两个字符串的值相等。(双等比较的是字符串的地址,而String类重写的equals方法比较的是字符串的值)
然后,我们来看如果都用直接赋值的方式进行比较:
String str1="Hello Word!";
String str2="Hello Word!";
System.out.println(str1==str2);
System.out.println(str1.equals(str2));
结果是true和true;由此可见,str1和str2指向的是相同的内存地址,而且两个字符串的值是相等的。
最后,让我们来看看都用构造函数的方式创建对象。
String str1=new String("Hello Word!");
String str2=new String("Hello Word!");
System.out.println(str1==str2);
System.out.println(str1.equals(str2));
结果是false和true;由此可见,str1和str2指向的是不同的内存地址,但是两个字符串的值相等。
直接赋值进行实例化的方式:在堆内存的字符串常量池中分配空间存储字符串,在栈内存中存储引用变量,只有String可以直接赋值进行实例化,其他类必须new一个对象出来才能完成实例化。String类的设计使用了共享设计模式,JVM底层会自动维护一个字符串常量池。直接赋值的方式在创建对象时,会先判断是否已经存在该实例化对象,如果没有,就会创建实例化对象保存在字符常量池中。如果有的话,就会直接引用。(两次直接赋值如果内容相同则会指向同一字符串对象。)
使用构建函数的方式实例化String对象:String str2=new String("Hello Word!");由于“Hello Word”也是一个String对象,因此,JVM会先在堆上创建一个“Hello Word!”字符串,再讲这个字符串复制一份并由str指向,这就导致出现了垃圾空间(”匿名String对象“Hello Word!”),并且如果采用构造方法的话,也不会将该字符串对象加入到JVM的“字符串常量池”中,导致字符串共享问题。
垃圾空间:如果使用String的构造方法就会开辟两块堆内存空间,并且其中一块堆内存将会变成垃圾空间。(字符串常量“Hello Word!”也是一个匿名对象,使用一次之后就不在使用,就成了垃圾空间,会被JVM自动回收);字符串共享:同一个字符串可能被存储多次,比较浪费空间。
为了解决“字符串共享”问题,可以使用String类的intern()
方法将构造方法方法方式创建的String对象手动加入到“字符串常量池”中。
String str1=new String("Hello Word!").intern();
String str2="Hello Word!";
System.out.println(str1==str2);
这时候的返回值是true,我们可以得到结果str1和str2指向的是同一个地址。即str1创建的对象入了JVM中的字符串常量池中,str2在字符串常量池中找到了“Hello Word!”,所以直接指向了改地址。
结论:
1.直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。
2.构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,默认不会自动保存在对象池中,可以使用intern()方法手工入池;但是并没有解决垃圾空间的问题。
总结,我们一般使用直接赋值的方式实例化String对象。
3.String的常用方法
方法 | 描述 |
---|---|
public String (char value[]) | 将一个char数组转换为字符串对象 |
public String (char value[],int offset,int count) | 将一个指定范围的char数组转换为字符串对象 |
public String (byte value[]) | 将一个byte数组转换为字符串对象 |
public String (byte value[],int offset,int count) | 将一个指定范围的byte数组转换为字符串对象 |
public int length() | 获取字符串长度 |
public boolean isEmpty() | 判断字符串是否为空 |
public char charAt(int index) | 返回指定下标的字符 |
public char[] toCharArray() | 返回char类型数组 |
public byte[] getBytes() | 返回byte类型数组 |
public boolean equals(Object anObject) | 判断两个字符串是否相等 |
public boolean equalsIgnoreCase(Object anObject) | 判断连个字符串是否相等(忽略大小写) |
public int compareTo(String value) | 对字符串进行排序(比较ASCII长度) |
public int compareToIgnoreCase(String value) | 对字符串进行排序(比较ASCII长度,忽略大小写) |
public boolean startsWith(String value) | 判断字符串是否以value开头 |
public boolean endsWith(String value) | 判断字符串是否以value结尾 |
public int hashCode() | 返回字符串的hash值 |
public int indexOf(String str) | 返回str在字符串中的下标 |
public int indexOf(char a) | 返回a在字符串中的下标 |
public int indexOf(String str,int fromIndex) | 从指定位置开始查找,返回str在字符串中的下标 |
public int indexOf(char a,int fromIndex) | 从指定位置开始查找,返回a在字符串中的下标 |
public String subString(int beginIndex,int endIndex) | 截取字符串 |
public String concat(String str) | 追加字符串 |
public String[] split(String regex) | 用指定的字符串对目标字符串进行分割,返回数组 |
public String toLowerCase() | 字符串转小写 |
public String toUpperCase() | 字符串转大写 |
注意:
1.前四个方法是构造方法的重载,使用的时候要注意。
2.null和空是两个概念。空是指对象存在,但是没有内容,长度为0;null是指对象不存在,引用地址为空(栈里面有,但是对里面没有)。这也就解释了为什么当String为null的时候调用isEmpty()
会报空指针异常,因为isEmpty()
是实例化方法,而null对象不存在。
3.下标是从0开始的!
4.返回字节数组和返回char类型数组方法名有很大区别,且字节数组中存储的是ASSII码值。
5.compareTo返回的是两个字符串的ASCII差值。
public int compareTo(String anotherString) {
byte v1[] = value;
byte v2[] = anotherString.value;
if (coder() == anotherString.coder()) {
return isLatin1() ? StringLatin1.compareTo(v1, v2)
: StringUTF16.compareTo(v1, v2);
}
return isLatin1() ? StringLatin1.compareToUTF16(v1, v2)
: StringUTF16.compareToLatin1(v1, v2);
}
6.public int indexOf(String str)默认查找首先出现的str的下标;如果没有返回负数。
7.public String subString(int beginIndex,int endIndex)截取的字符串,包含beginIndex,不包含int endIndex
8.public String concat(String str)并没有对原字符串进行修改,返回了一个匿名字符串。
9.public String[] split(String regex)使用的时候要注意指定的字符串是否要写成转义字符形式。常见应用场景:不同手机可能有数量不等的描述标签,如果每个标签都在设计数据库的时候设计出来,可能会造成浪费,就可以在数据库中就设置一个标签,然后使用某个字符将标签连接起来,使用的时候再拆分。
public class Demo5 {
public static void main(String[] args) {
//构造函数类型
char[] arrayChar={'H','e','l','l','o'};
String strChar1= new String(arrayChar);
String strChar2=new String(arrayChar,1,2);
System.out.println(strChar1);
System.out.println(strChar2);
byte[] arrayByte={'H','e','l','l','o'};
String strByte1=new String(arrayByte);
String strByte2=new String(arrayByte,1,2);
System.out.println(strByte1);
System.out.println(strByte2);
String str="Hello Word!";
String str1="";
String str2="Hello Word!";
String str3="hello word!";
//获取字符串的长度
System.out.println(str.length());
//判断字符串是否为空
System.out.println(str1.isEmpty());
//返回指定下标的数值
System.out.println(str.charAt(1));
//返回char类型数组
char[] charArray=str.toCharArray();
for(int i=0;i<charArray.length;i++){
System.out.print(charArray[i]+" ");
}
System.out.println();
//返回byte类型数组
byte[] byteArray=str.getBytes();
for(int i=0;i<byteArray.length;i++){
System.out.print(byteArray[i]+" ");
}
System.out.println();
//判断两个值是否相等
System.out.println(str.equals(str2));
System.out.println(str.equals(str3));
//判断两个值是否相等(忽略大小写)
System.out.println(str.equalsIgnoreCase(str3));
//比较ASCII差值
System.out.println(str.compareTo(str2));
System.out.println(str.compareTo(str3));
//判断字符串是否以某个字符串开始
System.out.println(str.startsWith("H"));
//判断字符串是否以某个字符串开始
System.out.println(str.endsWith("H"));
//返回str的hashcode值
System.out.println(str.hashCode());
//返回字符串/字符在str中的下标
System.out.println(str.indexOf("He"));
//从指定位置开始查找符串/字符在str中的下标
System.out.println(str.indexOf("l",3));
//从指定位置开始截取
System.out.println(str.substring(1,3));
//追加字符串
System.out.println(str.concat("aaaaa"));
//用指定的字符串对目标字符串进行分割,返回数组
String str4="Hello,Word,!,Java";
String[] strArray=str4.split(",");
for(int i=0;i<strArray.length;i++){
System.out.print(strArray[i]+" ");
}
System.out.println();
//字符串转小写
System.out.println(str.toLowerCase());
//字符串转大写
System.out.println(str.toUpperCase());
}
}
4.参考博客
参考博客:https://blog.csdn.net/weixin_43490440/article/details/101164178