-
目录
首先区别String中“==”和equals方法:
- “==”比较两个对象在内存中的首地址。
-
“equals()”原先和"=="用法相同,如在Object.class中:
public boolean equals(Object obj) {
return (this == obj);
}
但由于在String.class中重写了equals(),使其变为比较字符串中所包含的内容是否相同:
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
实践:
public static void main(String[] args){
String s1,s2,s3 = "abc", s4 ="abc" ;
s1 = new String("abc");
s2 = new String("abc");
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s3==s4);
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println(s3.equals(s4));
}
结果截图:
参考链接:https://www.cnblogs.com/weibanggang/p/9457757.html,https://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html,https://blog.csdn.net/qq_35885488/article/details/94838247
-
String创建对象的方式
首先了解String的数据类型:1、java中数据类型分为基本数据类型(byte、short、int、long、float、double、char、boolean)及引用数据类型(类class,数组array,接口interface);基本数据类型的内容会进入栈,被分配一块内存;引用数据类型指向真正内容的指针也会进入栈,被分配一块内存,而真正的内容被手动的分配在堆上。String就是引用数据类型。2、String是final类,说明栈值不变,改变的是引用指向的堆的值。
栈,堆和常量池:1、栈:存放基本类型的变量数据和对象的引用,但对象本身存放在堆(new 出来的对象)或者常量池中(字符串常量对象)2、堆:存放所有new出来的对象。3、常量池:存放字符串常量和基本类型常量(public static final)。
栈和常量池中的对象可以共享,堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
1.直接赋值
String s1 = "china";
String s2 = "china";
String s3 = "china";
执行“String s1 = "china";”后,JVM在常量池中开辟空间存放一个"china"字符串空间(即创建对象)并让s1指向该对象;
执行“String s2 = "china";”时,JVM会先检查常量池中是否已经存在了一个内容为china的空间,如果存在就直接让s2指向该空间,否则就会在开辟一个新的空间存放该字符串,所以,以上的第二行代码不会创建对象。
2.new
每new一次就会先去常量池中查找是否已经有了字符串对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此字符串对象的拷贝对象。
String ss1 = new String("china");
String ss2 = new String("china");
String ss3 = new String("china");
黄色这3个箭头:对于通过new产生一个字符串(假设为”china”)时,会先去常量池中查找是否已经有了”china”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”china”对象的拷贝对象。
注:
如果一个String是由两个常量运算得到的,相当于用双引号创建出来,会存入常量池,如:
String s = "a" + "b";
String t = "ab";//以上两种创建方式,完全等价
如果运算时,等号右边有一个“运算数”不为常量(即使该“运算数”是用双引号创建的常量),则得到的结果相当于new创建的一个新的String对象,如:
String str1 = "abc";
String str2 = "abcd";
String str3 = "abc" + "d";
String str4 = str1 + "d";
System.out.println(str2 == str3);//true
System.out.println(str2 == str4);//false
intern()方法的用法:intern方法是扩充常量池的一个方法,它会返回一个字符串对应的常量值。在执行intern方法时,JVM会检查常量池中是否存在和该字符串相同的常量值,如果有,则返回该常量值,若没有,则创建该常量值,并返回。即,intern返回的是值常量池中的String,不是堆上的String,相当于用双引号创建String。
String str1 = "abc";
String str2 = "abcd";
String str3 = "abc" + "d";
String str4 = (str1 + "d").intern();
System.out.println(str2 == str3);//true
System.out.println(str2 == str4);//true 注意和上例的区别
参考链接:https://www.iteye.com/topic/634530,https://blog.csdn.net/zhaobin0731/article/details/98450308,https://www.cnblogs.com/qingmuchuanqi48/p/10710835.html,https://blog.csdn.net/Mrs_chens/article/details/90601324
-
String中的一些常用方法
1) length():获取字符串的长度,即字符的个数
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.length()); //输出18
2)charAt(int index):获取指定索引处的字符
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.charAt(12)); //输出发
3)indexOf(String str):获取str在字符串对象中第一次出现的索引,默认从0位开始
indexOf(substring, int m) //默认从第m位开始;
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.indexOf('a'));//输出0
System.out.println(str.indexOf('a',5)); //输出9
4)substring(int start):从start开始截取字符串,包括start
String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.substring(1));//输出 dsfaxsdfas沙发上案发地方
System.out.println(str.substring(1, 12));//输出 dsfaxsdfas沙
5)isEmpty():判断指定字符串是否为空
String str="";
System.out.println(str.isEmpty());//输出true
String str1=" ";
System.out.println(str1.isEmpty());//输出false
6)concat(String str):在原有的字符串的基础上加上指定字符串
String str = "dr";
System.out.println(str.concat("eam"));//输出dream
7)toCharArray():把字符串转换为字符数组
public static void main(String[] args) {
String str = "adsfaxsdfas沙发上发地方";
char arr[] = str.toCharArray();
for(int i=0;i<a.length;i++) {
System.out.print(a[i]+"--");
}
}
//输出 a--d--s--f--a--x--s--d--f--a--s--沙--发--上--发--地--方--
8) startsWith(String prefix):判断字符串对象是否以指定的字符开头(区分大小写)
startsWith(String prefix,int toffset):判断字符串对象是否以指定的字符开头,参数toffset为指定从哪个下标开始
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.startsWith("a"));//输出true
System.out.println(str.startsWith("A"));//输出false
System.out.println(str.startsWith("f", 3));//输出true
System.out.println(str.startsWith("f", 8));//输出true
System.out.println(str.startsWith("f", 4));//输出false
9)toLowerCase():把字符串转换为小写字符串
toUpperCase():把字符串转换为大写字符串
String str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
System.out.println(str1.toLowerCase());//输出 abcdefghijklmnopqrstuvwxyz
String str2 = "abcdefghijklmnopqrstuvwxyz";
System.out.println(str2.toUpperCase());//输出 ABCDEFGHIJKLMNOPQRSTUVWXYZ
10)trim():去除字符串两端空格
String str3 = " a c e x u a n x u a n ";
System.out.println(str3.trim());//输出a c e x u a n x u a n
System.out.println(str3);//输出 a c e x u a n x u a n
11)split():根据指定字符分割字符串,然后返回一个新的字符数组
public static void main(String[] args) {
String str = "adsfaxsdfas沙发上发地方";
String array[] = str.split("d");
System.out.println(array.length);
}
//输出 3
12)subSequence(int beginIndex,int endIndex ):截取字符串中指定位置的字符组成一个新的字符串,包含beginIndex,不包含endIndex
String str = "adsfaxsdfas沙发上发地方";
System.out.println(str.subSequence(1, 10));//输出 dsfaxsdfa
13)replace(char oldChar, char newChar):将指定字符替换成另一个指定的字符,全部替换
replaceAll(String regex,String replasement):用新的内容替换全部旧内容
replaceFirst(String regex,String replacement):替换首个满足条件的内容
String str = "Hello,world,Helloabcd!";
System.out.println(str.replace("l", "&"));//输出He&&o,wor&d,He&&oabcd!
System.out.println(str.replaceAll("Hello", "w"));//输出w,world,wabcd!
System.out.println(str.replaceFirst("Hello", "w"));//输出w,world,Helloabcd!
14)contains(CharSequence s):查看字符串中是都含有指定内容
String str4 = "Hello,world!";
System.out.println(str4.contains("Hello"));//输出true
System.out.println(str4.contains("Helloworld"));//输出false
参考链接:https://blog.csdn.net/lz_1014/article/details/86241850