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不会
    }
}