以下为 Jean 学习笔记和习题整理,供学习和参考

# ==

1. 判断对象地址是否相等。eg:Integer 和 Integer

这里注意一下:IntegerCache 缓存

JAVA 的 Integer 有 IntegerCache 会缓存 - 128~127 之间的对象。

Integer 类型在 - 128-->127 范围之间是被缓存了的,也就是每个对象的内存地址是相同的,赋值就直接从缓存中取,不会有新的对象产生,而大于这个范围,将会重新创建一个 Integer 对象,也就是 new 一个对象出来,当然地址就不同了,也就!=;

Integer a = 1;
Integer b = 1;
Integer c = 500;
Integer d = 500;
System.out.print(a == b); // true
System.out.print(c == d); // false

2. 基本数据类型比较的是值。

eg:byte,short,char,int,long,double,boolean 用(==)、(!=)比较的都是值。

3. 引用数据类型比较的是内存地址。eg:Integer

总结:

1. 无论如何,Integer 与 new Integer 不会相等。不会经历拆箱过程,因为它们存放内存的位置不一样。

2. 两个都是非 new 出来的 Integer,如果数在 - 128 到 127 之间,则是 true, 否则为 false。

3. 两个都是 new 出来的,则为 false。

4.int 和 integer (new 或非 new) 比较,都为 true,因为会把 Integer 自动拆箱为 int,其实就是相当于两个 int 类型比较。

# equals

1. 判断两个对象是否相等

2. 类没有覆盖 equals 方法,等价于 “==” 比较两个对象。

注意:String 的 equals 是被重写过的 (hashCode 也被重写),Object 的 equals 是比较对象内存地址,String 创建对象时,JVM 在常量池中查找该对象,有无对应值,相同 -- 赋给当前值,不相同 -- 重新创建一个 String 对象

String str1="abc";
      String str2="abc";
      System.out.println(str1==str2);
      System.out.println(str1.equals(str2));
      // 结果都为 true,因为 str1 创建时在堆中开辟了一块新的内存,存储 abc,str 则保存在栈中,而 str2 在创建时,由于 abc 已经
      // 存在,所以直接把内存地址给 str2,而没有重新开辟新的内存地址,所以,打印结果都是 true
    String str3=new String("def");
    String str4=new String("def");
    System.out.println(str3==str4);
    System.out.println(str3.equals(str4));
    //== 打印的是 false,equals 打印的是 true, 因为 new String 不管之前的内容是否在内存中已经存在
    // 在新定义时,都会重新开辟一块内存来存储这块内容,从而 str3 和 str4 的内存地址是不同的。

new String () 的源码可以看出,new String () 会更改 hash 值,因为重新 new 出来的对象是会在堆中开辟内存来存储新对象的,内存地址不同,== 所返回的值肯定是不同的。

如果 hashcode 相等,equals 也一定相等。

3. 类覆盖了 equals 方法,内容相等,则返回 true

# ❓测试

# 1. 比较判断

@Test
	public void testEquals() {
		int int1 = 12;
		int int2 = 12;
		
		Integer integer1 = new Integer(12);
		Integer integer2 = new Integer(12);
		Integer integer3 = new Integer(127);
		
		Integer a1 = 127;
		Integer a2 = 127;
		
		Integer a = 128;
		Integer b = 128;
			
		System.out.println("int1 == int2 -> " + (int1 == int2));					
		System.out.println("int1 == integer1 -> " + (int1 == integer1));			
		System.out.println("integer1 == integer2 -> " + (integer1 == integer2));	
		System.out.println("integer3 == a1 -> " + (integer3 == a1));				
		System.out.println("a1 == a2 -> " + (a1 == a2));							
		System.out.println("a == b -> " + (a == b));													
	}

答案:

1、   int1 == int2 -> true
2、   int1 == integer1 -> true
    //nteger 是 int 的封装类,当 Integer 与 int 进行 == 比较时,Integer 就会拆箱成一个 int 类型,所以还是相当于两个 int 类型进行比较,这里的 Integer, 不管是直接赋值,还是 new 创建的对象,只要跟 int 比较就会拆箱为 int 类型,所以就是相等的。
3、   integer1 == integer2 -> false   // 两个都是对象类型比较的是地址
4、   integer3 == a1 -> false
    //integer3 是一个对象类型,而 a1 是一个常量它们存放内存的位置不一样,所以也不等
5、   a1 == a2 -> true
6、   a == b -> false
    // 看起来是一模一样的为什么一个是 true,一个是 false,这是因为 Integer 作为常量时,对于 - 128 到 127 之间的数,会进行缓存,也就是说 int a1 = 127 时,在范围之内,这个时候就存放在缓存中,当再创建 a2 时,java 发现缓存中存在 127 这个数了,就直接取出来赋值给 a2,所以 a1 == a2 的。当超过范围就是 new Integer () 来 new 一个对象了,所以 a、b 都是 new Integer (128) 出来的变量,所以它们不等。

# 2. 如何判断两个对象是否相等。

我们比较对象常用 equals(Object 的方法),你会发现,如果 User 类,使用默认的 equals () 方法判断 user1 和 user2 两个对象,得到的结果是 false。

public class User{
	private String name;
	private int age;
    // ...getter & setter
}

可以看一下 Object 的 equals 方法:

public boolean equals(Object obj) {
	return (this == obj);
}

因为默认的 equals 方法是判断两个对象的内存地址,在没有重写 equals 方法时调用的就是对象的 ==,即内存地址。在上面我们说到 == 比较两个引用对象比较的是地址。

User user1 = new User("小明",18);
User user2 = new User("小明",18);
System.out.println(user1.equals(user2));//false

那怎么判断 user1 就是 user2 呢?

如果要让 equals 比较的不是内存地址而是两个对象的内容就要对 equals 方法进行重写

@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;	
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
User user1 = new User("小明",18);
User user2 = new User("小明",18);
System.out.println(user1.equals(user2));//true
System.out.println(user1==user2);//false
System.out.println(user1.hashCode()); // 456789
System.out.println(user2.hashCode()); // 456789

equals 被重写时,有必要重写 hashCode, 以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

更新于

请我喝[茶]~( ̄▽ ̄)~*

Jean 微信支付

微信支付

Jean 支付宝

支付宝

Jean 贝宝

贝宝