微风·六·JAVA中“==”、hashcode、equals及字符串常量池的区别

news2024/12/24 8:27:46

vector线程安全的集合
hashset底层为hashmap

文章目录

  • 1 “==”和equals的区别是什么?
    • 1.1 “==”解释
    • 1.2 “equals”解释
    • 1.3 注意点:equals不能比较基本数据类型
    • 1.4 Integter缓存数组
      • 1.4.1 引入案例发现问题
      • 1.4.2 解释缓存数组
    • 1.5 字符串常量池
      • 1.5.1 案例一
      • 1.5.2 案例二
      • 1.5.3 案例三
      • 1.5.4 案例4
      • 1.5.5 案例5
      • 1.5.6 案例6
      • 1.5.7 案例7
      • 1.5.8 案例8
      • 1.5.9 案例9
  • 2 两个对象的hashcode值相同,则equals是否也相同?
    • 2.1 不对,两者间没有太大的关系
    • 2.2 重写的hashCode方法调用
    • 2.3 Arrays的hashCode方法
  • 3 重写equals的时候需不需要重写hashcode呢?

1 “==”和equals的区别是什么?

  • “= =”是运算符,如果是基本数据类型,比较是存储的值: int i = 100; int j = 100; i= =j;true
  • 若是引用数据类型,比较的是所指向对象的地址值:User user1 = new User(); User user2 = new User(); user1= =user2; false

1.1 “==”解释

“==”是运算符

  • ① 若相比对象是基本数据类型,则比较存储值是否相等;
  • ② 若相比是引用数据类型,则比较是所指向对象的地址值是否相等。

案例:

        final String str2 = "ab";//在字符串常量池中创建“ab”,并将地址值赋值给str2
        System.out.println(str2);
        final String str3 = "cd";//在字符串常量池中创建“cd”,并将地址值赋值给str3
        System.out.println(str3);
        String str6 = new String("abcd");//在堆中开辟地址空间,并把得到的地址值赋值给str6
        String str4 = str2+str3;//在字符串常量池中得到abcd的地址
        System.out.println(str4);

        String str5 = "abcd";//在字符串常量池中创建abcd时,发现已有,不用创建,就使用创建好的地址值
        System.out.println("str4 = str5 : " + (str4==str5));//true

        System.out.println("str6 = str5 : " + (str6==str5));//false

1.2 “equals”解释

equals是Object的方法,用来比较两个对象地址值是否相等。

源码如下(其底层仍是“==”):
在这里插入图片描述

案例:

        final String str2 = "ab";//在字符串常量池中创建“ab”,并将地址值赋值给str2
        System.out.println(str2);
        final String str3 = "cd";//在字符串常量池中创建“cd”,并将地址值赋值给str3
        System.out.println(str3);
        String str6 = new String("abcd");//在堆中开辟地址空间,并把得到的地址值赋值给str6
        String str4 = str2+str3;//在字符串常量池中得到abcd的地址
        System.out.println(str4);

        String str5 = "abcd";//在字符串常量池中创建abcd时,发现已有,不用创建,就使用创建好的地址值
        System.out.println("str4 = str5 : " + (str4==str5));//true

        System.out.println("str6 = str5 : " + (str6==str5));//false
        System.out.println(str6.equals(str4)); //true :String底层重写了equals比较的是对象的内容

1.3 注意点:equals不能比较基本数据类型

equals不能用于比较基本数据类型,如果没有对equals进行重写,则相当于“==”,比较的是引用数据类型变量所指地址值。

  • 注意:我们自定义的对象需要重写equals方法,一般情况下,类会重写equals方法用来比较两对象内容是否相等。如:String类中的equals()是被重写了,比较的是对象的内容。
    在这里插入图片描述

1.4 Integter缓存数组

1.4.1 引入案例发现问题

问题:我们发现,首先Integter是引用数据类型,但是,我们在做这两次比较判断的时候,却得到了两次不一样结果,如果说第二个FALSE得出是正常的,那第一个TRUE出现究极奇怪。
在这里插入图片描述

1.4.2 解释缓存数组

  • ① Integter有一个缓冲数组,将-128~127的所有数值,创建成Integter对象,提前放入到数组中。
  • ② i=100和i2=100,都是从数组中获取Integter对象,因为获取的是同一个,所以最终结果返回TRUE。
  • ③i3=300和i4=300,因为数组中不存在,则需new Integter()创建两次对象,两次对象的地址值不同,所以结果返回FALSE。

1.5 字符串常量池

注意:“==”号,在引用数据类型中,比较的都是地址值

1.5.1 案例一

        final String str2 = "ab";//在字符串常量池中创建“ab”,并将地址值赋值给str2
        System.out.println(str2);
        final String str3 = "cd";//在字符串常量池中创建“cd”,并将地址值赋值给str3
        System.out.println(str3);
        String str6 = new String("abcd");//在堆中开辟地址空间,并把得到的地址值赋值给str6
        String str4 = str2+str3;//在字符串常量池中得到abcd的地址
        System.out.println(str4);

        String str5 = "abcd";//在字符串常量池中创建abcd时,发现已有,不用创建,就使用创建好的地址值
        System.out.println("str4 = str5 : " + (str4==str5));//true

        System.out.println("str6 = str5 : " + (str6==str5));//false
        System.out.println(str6.equals(str4)); //true :String底层重写了equals比较的是对象的内容

1.5.2 案例二

String s1 = new String("abc");//堆中开辟新空间,得到新地址值
String s2 = new String("abc");//堆中开辟新空间,得到新地址值
System.out.println(s1 == s2);//false
System.out.println(s1.equals(s2)); // true:底层重写了equals方法

1.5.3 案例三

String s1 = "abc";//字符串常量池中创建abc,得到地址值
String s2 = new String("abc");//堆中开辟新空间,得到新地址值
s2.intern();//可以拿到s2的常量
System.out.println(s1 ==s2);//false

1.5.4 案例4

String str1 = "ab" + "cd";//先做计算得到abcd,字符串常量池中创建,并得到地址值
String str11 = "abcd";//字符串常量池发现已有,直接得到地址值
System.out.println("str1 = str11 : "+ (str1 == str11)); //TRUE

1.5.5 案例5

String str2 = "ab";//字符串常量池中创建,并得到地址值
String str3 = "cd";//字符串常量池中创建,并得到地址值
String str4 = str2+str3;//此处相当于str2+new String(str3)
String str5 = "abcd";//字符串常量池发现已有,直接得到地址值
System.out.println("str4 = str5 : " + (str4==str5));//false

1.5.6 案例6

final String str2 = "ab";//被final修饰的变量只能被赋值一次
final String str3 = "cd";//被final修饰的变量只能被赋值一次
String str4 = str2+str3;//“ab”+"cd"="abcd",并在字符串常量池中创建abcd,得到地址值
String str5 = "abcd";//字符串常量池发现已有,直接得到地址值
System.out.println("str4 = str5 : " + (str4==str5));//TRUE

1.5.7 案例7

String str6 = "b";//字符串常量池中创建b,得到其地址值
String str7 = "a" + str6;//此处相等于:“a”+new String(str6)
String str67 = "ab";//字符串常量池中创建ab,得到其地址
System.out.println("str7 = str67 : "+ (str7 == str67));//false

1.5.8 案例8

final String str8 = "b";//final修饰的变量,只能被赋值一次
String str9 = "a" + str8;//此处相等于:“a”+“b”先做计算得到值:ab,并在字符串常量池中创建ab,得到其地址值
String str89 = "ab";//在字符串常量池中,创建ab是发现已有,得到其地址值
System.out.println("str9 = str89 : "+ (str9 == str89)); //TRUE

1.5.9 案例9

String s1="Hello";//字符串常量池中创建并得到地址值
String s2="hello";//字符串常量池中创建并得到地址值
String s3=s1.toLowerCase();//将大写转为小写,但是地址值仍是先前的
String s4=s2.toLowerCase();//将大写转为小写,但是地址值仍是先前的
System.out.println(s3==s4);//false,==号在引用数据类型是比较的是地址值

2 两个对象的hashcode值相同,则equals是否也相同?

2.1 不对,两者间没有太大的关系

2.2 重写的hashCode方法调用

调用时以下算法
在这里插入图片描述

2.3 Arrays的hashCode方法

element.hashCode方法是native(用C语言写的)方法,无法再查看源码,不过能确定的是用个了啥算法。
因此,极端情况下,会发生哈希碰撞,即出现地址值相同结果
在这里插入图片描述

3 重写equals的时候需不需要重写hashcode呢?

需要重写

  • ① 当重写了equals和hashcode时,比如给HashMap存入数据时,先计算key的hash值,然后对数组长度取余,得到key在数组照片那个存储的位置,其次使用equals比对要存入的位置是否已有相同的数据,若相同,则替换,若不同,存入数组下面的链表中。
  • ②若自定义类中,没有重写hashcode方法,会调用其父类Object中的hashcode方法,默认是根据地址进行哈希运算,结果:两个值相同的对象实例,其hashcode值不一样,存入相同值在Map中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/450579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频直播网站开发的最佳实践

随着互联网技术的不断发展,视频直播成为了网络世界中的一股热潮。无论是企业还是个人,都可以通过搭建自己的视频直播网站来实现自己的目标。但是,对于很多企业来说,视频直播网站的开发是一项复杂的任务。因此,本文将介…

响应式开发(HTML5CSS3)实现媒体查询的功能案例

目录 前言 一、媒体查询知识点 二、实现功能的尺寸 三、代码部分 1.不带嵌套的媒体查询功能 1.1.代码段 1.2.运行结果 2.带嵌套的媒体查询功能 2.1.代码段 2.2.运行结果 2.2.3视频效果 前言 1.本文讲解的响应式开发技术(HTML5CSS3Bootstrap&#xff09…

C语言开发环境搭建及调试

C简介 可移植 标准C C/C (系统硬件操作的接口,windows,Linux不一样) 跨平台 Java Python 下载 去官网选择Visual Studio 2019下载 安装过程中勾选使用C的桌面开发 安装好之后点击创建新项目——空项目 位置最好放在根目录下&…

从数据管理到数据资产管理

数据已经与土地、劳动力、资本、技术并称为五种生产要素,数据的价值是毋庸置疑的。数据甚至成为了国家的基础性战略资源,数字经济也正在成为经济增长的强大创新动力。那么—— 数据到底指的是什么? 数据管理又是怎么回事? 数据如何…

Django项目之经济预测平台,应用LSTM、GBDT等算法

一、平台功能与技术点 1.技术点:Python3.9、Django4.1.7, tensorflow2.11.0,keras2.11.0,numpy1.24.2、bootstrap、ajax、MySQL等等 2.功能:正常前后端,前台主要完成经济预测功能(特征和标签都…

✨✨✨ ❃ ♕ ꕥXpath解析html获取表情符号,丰富你的文章 ꧁ ꧂꧁ ꧂

✨✨✨ ❃ ♕ ꕥXpath解析html获取表情符号,丰富你的文章 ꧁ ꧂꧁ ꧂ 1. 推荐几个好玩的表情符号网站2. xpath解析html获取表情3. xpath解析html源码3.1 parse_li.py3.2 symbol2.html 参考 1. 推荐几个好玩的表情符号网站 💕 🧚 &#x1f6b…

SPDK软件栈基础概念

SPDK SPDK软件架构SSD和SPDK中controller和nsSPDK RPC (一)driverSPDK virtio-PCIe 和 vhost-user (二)Storage Services(存储设备)对象存储SPDK BlobStore&BlobFS SPDK 块设备驱动块设备驱动层的其他模块 (三&…

KMP字符串匹配算法详解

目录 简单的暴力匹配算法KMP算法next数组next数组的优化 简单的暴力匹配算法 对于字符串的匹配通常是给出一个主串str和一个模式串sub,然后在主串pos位置开始匹配,如果能在str中找到sub那么就返回sub在str中首次出现的首个字符的下标,否则返…

地球系统模式(CESM)

目前通用地球系统模式(Community Earth System Model,CESM)在研究地球的过去、现在和未来的气候状况中具有越来越普遍的应用。CESM由美国NCAR于2010年07月推出以来,一直受到气候学界的密切关注。近年升级的CESM2.0在大气、陆地、海…

【论文笔记】VideoGPT: Video Generation using VQ-VAE and Transformers

论文标题:VideoGPT: Video Generation using VQ-VAE and Transformers 论文代码:https://wilson1yan. github.io/videogpt/index.html. 论文链接:https://arxiv.org/abs/2104.10157 发表时间: 2021年9月 Abstract 作者提出了…

git 常用命令及遇到问题

自己没事,把git常用命令做个记录总结。方便自己和初学者查看,本文针对初学者,如果你已经是工作多年高手,请跳过。 git的几个区认识,分别为工作区,缓存区,版本库。 工作区:包含.git…

靶机精讲:BNE0x03Simple

主机发现 nmap扫描 端口扫描 服务扫描 脚本扫描 第二十页路径有目录 web渗透 搜索该版本漏洞 CuteCMS漏洞利用 下载下来 查看文件,发现是远程文件上传漏洞 按步骤进行注册 点进去 构造利用文件,反弹shell 最后语法错误应为0>1 尝试上传 根据漏洞扫…

实验04:图像压缩(DP算法)

1.实验目的: 掌握动态规划算法的基本思想以及用它解决问题的一般技巧。运用所熟悉的编程工具,运用动态规划的思想来求解图像压缩问题。 2.实验内容: 给定一幅图像,求解最佳压缩,使得压缩后的文件最小。 3.实验要求…

容易忽视的细节:Log4j 配置导致的零点接口严重超时

作者:vivo 互联网服务器团队- Jiang Ye 本文详细的记录了一次0点接口严重超时的问题排查经历。本文以作者自身视角极具代入感的描绘了从问题定位到具体的问题排查过程,并通过根因分析并最终解决问题。整个过程需要清晰的问题排查思路和丰富的问题处理经验…

大话数据结构-查找

1 查找概论 查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合,如下所示:   关键字(Key)是数据元素中某个数据项的值,又称为键值,用它可以标…

LiteFlow规则引擎的入门

文章目录 1、LiteFlow简介2、解决的痛点3、快速开始3.1 引入依赖3.2 配置规则文件的位置3.3 定义组件3.4 指定规则3.5 编写客户端3.6 运行以及说明3.7 其他的组件 4、对于快速开始的思考5、LiteFlow的脚本组件5.1 脚本的定义5.2 脚本的使用5.3 关于脚本使用的思考 6、规则引擎的…

开源Qt Ribbon控件——SARibbon的布局思路及介绍

开源Qt Ribbon控件——SARibbon的布局思路及介绍 SARibbon的布局SARibbon名词定义Office布局模式——SARibbonBar::OfficeStyleWPS布局模式——SARibbonBar::WpsLiteStylepannel的布局行数3行模式2行模式 原文链接:https://blog.csdn.net/czyt1988/article/details/…

scala之基础面向对象

scala 既是面向对象 也是函数式编程 从Java 发展而来,依赖JVM环境 一、 scala 在linux中运行 scala 模式中直接编写运行 scala文件,load执行 scala编译程序 编译 运行 scala java 二、scala 数据类型 基础数据类型 val 不可变变量 函数式编程 …

Excel使用频率超高的20个函数,90%你没用过

上班必学必会的Excel函数,不仅是使用频率最大的,还是告别加班的利器。你会的函数越多,解决问题的思路越广,不再束手束脚。态度决定高度,细节决定成败。要想比别人更优秀,只有在每一件小事上比功夫。 组合、…

json-c交叉编译及库移植

编译后的文件 json-c交叉编译及库移植资源-CSDN文库 json-c开源库是一个用c实现的解析json字段的库,嵌入式领域比较实用的库。 由于应用程序需要,需要找移植这个json-c库,所以这里对该库的移植做个简单说明 json-c开源库是一个用c实现的解…