1.a == b:
对于基本数据类型 == 比较的是值;对于引用数据类型 == 比较的是对象的内存地址。
2.a.equals(b)
:
a和b必须是引用数据类型。
它的作用也是判断两个对象是否相等。但它一般有两种使用情况:。
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于调用了Object类的equals() 方法,也就是通过“==”比较这两个对象。比如StringBuffer类中的equals()方法,调用了Object类的equal方法,未覆盖,用于比较对象的内存地址。
情况2:类覆盖了 equals() 方法。一般,我们都会覆盖 equals() 方法来判断两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。比如String类中的equals() 方法,已覆盖,比较的是对象的值。
注意:
- 因为String中的equals方法是被重写过的,而StringBuffer没有重写equals方法,从而调用的是Object类的equals方法,也就相当于用了
==,比较的是对象的内存地址
;- 对于基本类型的包装类型,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double等的引用变量,==是比较地址的,而equals是比较内容的。
3.String与new String()的区别
JVM为了提升性能和减少内存开销,避免字符串的重复创建,维护了一块特殊的内存空间——字符串实例池。
String赋值的两种方式。
1、String a = "zl";
以这种方式赋值时,JVM会先从字符串实例池中查询是否存在"zl"这个对象,
如果存在,直接把实例池中"zl"的地址返回给a。
如果不存在,则会在实例池中创建"zl"对象,并把该对象的地址返回给a,即a存的是"zl"对象的地址。
String a = "zl";//此时实例池中不存在“zl”这个对象,所以会在实例池中创建"zl"对象,并把该对象的地址返回给a,即a存的是"zl"对象的地址。
String b = "zl";//此时实例池中存在“zl”这个对象,所以会直接把实例池中"zl"的地址返回给b。
所以a,b指向的是同一地址,所以返回true;
2、String a= new String("zl");
以这种方式赋值时,JVM会先从字符串实例池中查询是否存在"zl"这个对象,
若不存在则会在实例池中创建"zl"对象,同时在堆中创建"zl"这个对象,然后将堆中的这个对象的地址返回给a。
若实例池存在则直接在堆中再创建一个"zl"这个对象,然后将堆中这个新创建对象的地址返回给a。
String a = new Sring("zl");//此时在实例池和堆中均创建了“zl”这个对象,并且将堆中的这个对象的地址返回给a。
String b = new Sring("zl");//此时实例池中已有“zl”这个对象,则直接在堆中创建“zl”这个对象,并将堆中的这个对象的地址返回给b。
所以a和b存的是不同的内存地址,所以返回false;
代码演示:
package cn.tedu.test4;
public class EqualsDemo {
public static void main(String[] args) {
String a= "zl";
String b= "zl";//注意:要区分String与new String的区别。
// String a = new Sring("zl");
// String b = new Sring("zl");//String 类中的equals()方法已经覆盖,用于比较对象的内容(已覆盖,比较值)
if(a==b) { //a,b是引用数据类型,比较对象的内存地址
System.out.println("a==b");
}else {
System.out.println("a!=b");
}
if(a.equals(b)) { //比较值
System.out.println("String equal true");
}else {
System.out.println("String equal false");
}
StringBuilder c = new StringBuilder("zjn");
StringBuilder d = new StringBuilder("zjn");//StringBuilder 类未覆盖equals()方法,用于比较对象(未覆盖,比较对象)
if(c==d) { //比较对象的内存地址
System.out.println("c==d");
}else {
System.out.println("c!=d");
}
if(c.equals(d)) { //比较对象
System.out.println("StringBuilder equal true");
}else {
System.out.println("StringBuilder equal false");
}
}
}
使用String直接定义时结果显示:
a==b
String equal true
c!=d
StringBuilder equal false
使用new String定义时结果显示:
a!=b
String equal true
c!=d
StringBuilder equal false
String常用方法
• length()-查看字符串的长度
• charAt()—获取指定下标处位置上的字符
• lastIndexOf()-某个字符最后一次出现的位置
• substring()-截取子串,如果参数有两个左闭右开[1,5)
• equals()-判断两个串是否相等,注意String重写了Object的此方法,所以内容相同就返回true
• startsWith()-判断是不是以参数开头
• endsWith()–判断是不是以参数结尾
• split()—以指定字符分割
• trim()-去掉首尾两端的空格
• getBytes()-把串转换成数组
• toUpperCase()-变成全大写
• toLowerCase()-变成全小写
• String.valueOf(10)-把int类型的10转换成String类型
代码演示
package cn.tedu.api;
import java.util.Arrays;
public class Homework {
public static void main(String[] args) {
String s1 = "abC";
char[] value = {'a','b','C'};
String s2 = new String(value);
System.out.println(s1 == s2);//false,比较引用类型对象,比较的是地址值是否相等
System.out.println(s1.equals(s2));// true,String重写了equals()方法,此时比较的是具体值
System.out.println(s1.toLowerCase());//abc,将字符串全部转为小写
System.out.println(s2.toUpperCase());//ABC,将字符串全部转为大写
System.out.println(s1.length());//3,获取字符串长度
System.out.println(s1.concat("def"));//abCdef,拼接字符串,但不会影响原s1字符串内容,而是新创建了一个地址空间存放abCdef
System.out.println(s1);//abC
System.out.println(String.valueOf(1)+10);//110,将整型转为字符串类型,拼接10
System.out.println(String.valueOf('a')+10);//a10
System.out.println(s1.substring(1));//截取下标为1及之后的字符串
System.out.println(s1.substring(0,2));//截取位置下标为0至2(不包括2)的字符串
System.out.println(s1.charAt(2));//获取指定下标位置的字符
String s3 = new String(" abCdef ");
System.out.println(s3.startsWith("b"));//false,判断字符串是否是以b开头
System.out.println(s3.endsWith(" "));//true,判断字符串是否是以空格结尾
System.out.println(s3.trim());//abCdef,去除字符串收尾两端的空格
System.out.println(Arrays.toString(s3.getBytes()));//将字符串元素转为字节码形式,并以数组输出
System.out.println(s3.indexOf("b"));//-1,获取目标字符串在原字符串中的位置,若不存在,则返回-1
System.out.println(s3.indexOf("1")+10);//9,-1+10=9
System.out.println(s3.lastIndexOf(1));//-1,获取目标字符串在原字符串中最后一次出现的位置,若不存在,则返回-1
System.out.println(s3.lastIndexOf("e"));//5
String s4 = "ab C de f";
System.out.println(Arrays.toString(s4.split(" ")));//[ab, C, de, f]以空格为分隔符将字符串分割,分割后以数组的形式输出
System.out.println(Arrays.toString(s4.split(" ",2)));//[ab, C de f]以空格为分隔符将字符串分割,限制分割的份数为2份
String s5 = new String("ab C de f");
System.out.println(s4 == s5);//false,比较两个引用类型对象的地址值是否相等
System.out.println(s4.equals(s5));//true,String对equals()方法进行了重写,比较的是两个对象的具体值
StringBuffer s6 = new StringBuffer("ab C de f");
StringBuffer s7 = new StringBuffer("ab C de f");
System.out.println(s6 == s7);//false,比较两个引用类型对象的地址值
System.out.println(s6.equals(s7));//false,StringBuffer没有重写equals()方法,所以比较的是地址值
System.out.println(s6.append("g"));//ab C de fg,在字符串末尾增加字符(字符串拼接)
System.out.println(s6);//ab C de fg,StringBuffer拼接后会影响原字符串内容,而String不会
}
}