【JAVA】== 和 equals

一、integer的==

public class Test03 {
 
     
    public static void main(String[] args) {
        
        Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
 
          
        System. out.println( f1 == f2); //true
        System. out.println( f3 == f4); //false
    }
}

当我们给一个 Integer 赋予一个 int 类型的时候会调用 Integer 的静态方法 valueOf。
Integer f1 = Integer.valueOf(100);
Integer f2 = Integer.valueOf(100);
Integer f3 = Integer.valueOf(150);
Integer f4 = Integer.valueOf(150);
思考:那么 Integer.valueOf()返回的 Integer 是不是是重新 new Integer (num); 来创建的呢?如果是这样的话,那么 == 比较返回都是 false,因为他们引用的堆地址不一样。

具体来看看 Integer.valueOf 的源码

public static Integer valueOf(int i) {
         //范围-128到127
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}

从上面我们可以知道给 Interger 赋予的 int 数值在 - 128 - 127 的时候,直接从 cache 中获取,这些 cache 引用对 Integer 对象地址是不变的,但是不在这个范围内的数字,则 new Integer (i) 这个地址是新的地址,不可能一样的.


二、string的==

  1. String str=new String ("abc") 和 String str="abc" 的字符串 “abc” 都是存放在堆中,而不是存在栈中。

  2. 其实在在 java 中有一个 “字符数据池” 的内存管理机制。

  3. String str="abc",执行这句话时,会先去 “字符数据池” 搜索时候有 “abc” 这个字符串,如果有,则将字符串的首地址赋值给 str,如果没有,生成一个新的字符串 “abc” 并且将首地址赋值给 str;

  4. String str=new String ("abc"),执行这句话时,不会考虑时候已经存在了 “abc” 这个字符串,而是直接生成一个新的字符串 “abc” 并将首地址赋值给 str,如果池中没有字符串,则把这个"abc"放入字符串池中(此时是创建了两个对象,一个堆中,一个池中);

  5. 由以上分析可知,String str="abc" 和效率要高于 String str=new String ("abc"),因为如果有重复的字符串时,第一种方式可以节省空间。

  6. 下面举例说明一下,好好看看结果,仔细分析原因,上面已经说明的很清楚了:

public class Test{
 public static void main(String args[]){
  String s1=new String ("abc");// 直接在堆中生成新的 “abc”
  String s2=new String ("abc");// 直接在堆中生成新的 “abc”
  String s3="abc";// 先去 “字符数据池” 搜索时候有 “abc” 这个字符串,如果有,则将字符串的首地址赋值给 s3,如果没有,则在 “字符数据池” 中生成一个新的字符串 “abc” 并且将首地址赋值给 s3;  
  String s4="abc";// 去 “字符数据池” 搜索时发现了上一步生成的 “abc” 这个字符串,把该字符串首地址赋值给 s4,这时其实 s3 和 s4 指向同一个字符数据池中的 “abc”
  System.out.println(s1==s2);
  System.out.println(s1==s3);
  System.out.println(s2==s3);
  System.out.println(s3==s4);
 }
}

结果:
false
fasle
false
true


三、基本类型和包装类的==和equals(涉及拆装箱)

1、基本型和基本型的封装型进行 "= =" 运算符的比较,基本型的封装型将会自动拆箱变为基本型后再进行比较,因此 Integer (0) 会自动拆箱为 int 类型再进行比较,显然返回 true;

2、两个 Integer 类型进行 "= =" 比较,如果其值在 - 128 至 127,那么返回 true,否则返回 false, 这跟 Integer.valueOf () 的缓冲对象有关,这里不进行赘述。

3、两个基本型的封装型进行 equals () 比较,首先 equals () 会比较类型,如果类型相同,则继续比较值,如果值也相同,返回 true

4、基本型封装类型调用 equals (), 但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行 3 中的比较。

5、对于equal方法来说,如果没有重写过,那么就是相当于==,equals方法是基类Object的方法,所有对象都可以调用这个方法,而equals底层实现就是==,也就是直接比较地址的,所以呢,如果没有重写equal方法的对象调用equal方法,是直接比较对象地址的。


四、关于equal和 == 的总结

  1. '==' 是用来比较两个变量(基本类型和对象类型)的值是否相等的, 如果两个变量是基本类型的,那很容易,直接比较值就可以了。如果两个变量是对象类型的,那么它还是比较值,只是它比较的是这两个对象在栈中的引用(即地址)

  2. 对象是放在堆中的,栈中存放的是对象的引用(地址),由此可见 '==' 是对栈中的值进行比较的。如果要比较堆中对象的内容是否相同,那么就要重写 equals 方法了。

  3. Object 类中的 equals 方法就是用 '==' 来比较的,所以如果没有重写 equals 方法(string是重写了equal方法的),equals 和 == 是等价的。 通常我们会重写 equals 方法,让 equals 比较两个对象的内容,而不是比较对象的引用(地址)因为往往我们觉得比较对象的内容是否相同比比较对象的引用(地址)更有意义。

  4. Object 类中的 hashCode 是返回对象在内存中地址转换成的一个 int 值(可以就当做地址看)。所以如果没有重写 hashCode 方法,任何对象的 hashCode 都是不相等的。通常在集合类的时候需要重写 hashCode 方法和 equals 方法,因为如果需要给集合类(比如:HashSet)添加对象,那么在添加之前需要查看给集合里是否已经有了该对象,比较好的方式就是用 hashCode。

  5. 注意的是 String、Integer、Boolean、Double 等这些类都重写了 equals 和 hashCode 方法,这两个方法是根据对象的内容来比较和计算 hashCode 的。(详细可以查看 jdk 下的 String.java 源代码),所以只要对象的基本类型值相同,那么 hashcode 就一定相同。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 四、集合框架 1:String类:字符串(重点) (1)多个字符组成的一个序列,叫字符串。生活中很多数据的描述都采...
    佘大将军阅读 732评论 0 2
  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 825评论 1 6
  • == 基本数据类型的==比较的值相等,类的==比较的内存的地址,即是否是同一个对象 equals equals是O...
    沉淀之际阅读 132评论 0 0
  • 前言 本篇文章讲的是从JVM角度比较==和equals的区别 一:** Java数据类型分类** 1:基本数据类型...
    IT人生阅读 5,410评论 3 8
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,483评论 0 3