AndroidJava List与equals的微妙关系,小心掉坑里

前言

List 有多个实现,本文以ArrayList(LinkedList也一样)作为说明,equals是Object的一个成员函数,例子中的bean重写实现它。

一、Bean 类定义并重写equals函数

public class Book {private String id;private String name;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic boolean equals(Object obj) {//这里重写if (obj instanceof Book) {//obj是book对象,使用当前对象id与obj的id进行对比return id == null ? false : id.equals(((Book) obj).id);} else if (obj instanceof String) {//目的可以接受id进来匹配是不是同一本书(我们得到id,不需要构造一个book对象来进行匹配对比)return obj.equals(id);}return false;}
}

二、equals的演练

  1. Bean 对象 vs Bean对象
public static void main(String[] args) {Book book1 = new Book();book1.setId("111");book1.setName("语文");Book book2 = new Book();book2.setId("222");book2.setName("数学");println("book1 equals book2 ? " + book1.equals(book2));
}

book1 equals book2 ? false

book2作为参数,book1对象调用equals函数,id不一样,结果自然是false。

  1. Bean对象 vs String 对象
public static void main(String[] args) {String id = "111";Book book1 = new Book();book1.setId(id);book1.setName("语文");println("book1 equals String ? " + book1.equals("111"));
}

book1 equals String ? true

字符串"111"作为参数,book1对象调用equals函数,结果是true。这也符合我们重写equals的目的。

List演练

我们知道,list中包含某个对象,是通过遍历list的每一个元素和给定的对象相匹配,如果匹配上说明包含,反之不包含,且匹配也是调用equals函数。
看如下代码:

 public static void main(String[] args) {String id = "111";Book book1 = new Book();book1.setId(id);book1.setName("语文");Book book2 = new Book();book2.setId("222");book2.setName("数学");ArrayList list = new ArrayList(2);list.add(book1);list.add(book2);println("list contains book1 ? " + list.contains(book1));println("list contains id 111 ? " + list.contains("111"));
}

执行结果:

list contains book1 ? true
list contains id 111 ? false

结果不是我们期望的,前面已经验证 book1.equals(“111”)的结果是true,list.contains(“111”)的结果是false。
不急,来看看ArrayList的contains实现(contains实际上是调用了indexOf函数):

 public boolean contains(Object o) {return indexOf(o) >= 0;}/*** Returns the index of the first occurrence of the specified element* in this list, or -1 if this list does not contain the element.* More formally, returns the lowest index <tt>i</tt> such that* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,* or -1 if there is no such index.*/public int indexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++)if (elementData[i]==null)return i;} else {for (int i = 0; i < size; i++)//因为这个判断用的是o.equals,所以不包含111if (o.equals(elementData[i]))return i;}return -1;}

for (int i = 0; i < size; i++)确实是遍历了所有元素。问题在于if (o.equals(elementData[i]))
这里调用的是参数对象的equals,不是调用元素对象的equals函数。如果反过来if (elementData[i].equals(o))那么我们上面的结果就是true。

通俗的讲,list.contains(“111”),contains函数中匹配时,是"111".equals(elementData[i]),不再是book.equals(“111”)。

总体来说,我们有重新实现equals的情况下,在使用list的时候要避免使用非本类的对象匹配方式,一定要同类如:list.contains(book1)。上面的情况请用111 构造出一个Book对象才能得到正确的结果。当然,list的indexOf也是如此。

那么代码上为什么有这样的坑呢,应该为了代码简练,如果写成elementData[i].equals(o)的话,elementData[i]需要进行判空。
有知道更多原因的请留言,抱拳谢过。

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

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

相关文章

apache缺省banner_http服务器缺省banner

HTTP协议详解(真的很经典)HTTP协议详解(真的很经典)Author :清晨引言HTTP是一个属于应用层的面向对象的协议&#xff0c;由于其简捷、快速的方式&#xff0c;适用于分布式超媒体信息系统。它于1990年提出&#xff0c;经过几年的使用与发展&#xff0c;得到不断地完善和扩展。目…

GenseeSDK 使用Kotlin要注意TODOAndroid Studio关闭TODO

目录一、Kotlin的TODO二、GenseeSDK与TODO 请注意三、Android studio关闭TODO一、Kotlin的TODO 在实现一些接口时候&#xff0c;工具自动将所有的接口函数"空"实现&#xff0c;并在函数体中增加一行代码&#xff1a; TODO或TODO(“not implemented”) 作为提醒催促…

如何启动netcat_Netcat用法

Netcat用法--服务泄漏内部信息要得到某些端口号的详细信息&#xff0c;可以连接到某个端口&#xff0c;对应的服务会告知它的版本号、结构甚至其工作的操作系统。所以&#xff0c;可以使用Netcat来扫描一个特定范围内的端口并报告在这些端口上运行的服务。要使Netcat自动工作&a…

AndroidJava try-catch-finally正确用法

目录一、try-catch-finally的用途二、try-catch的正确使用三、奇怪的try-finally &#xff08;错误的用法&#xff09;四、关于try-catch-finally的面试考察1、try、catch、finally 考察&#xff0c;请指出下面程序的运行结果。2、try、catch、finally 考察2&#xff0c;请指出…

python tcp服务器并发_python tcp并发服务器

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":6,"count":6}]},"card":[{"des":"云服务器 ECS(Elastic Compute Service)是一…

OpenCV Mat基础认知感

OpenCV是一个开源的供开发的计算机视觉处理库&#xff0c;涵盖的内容包括图像处理&#xff0c;机器学习。由c到c &#xff0c;再到各平台的跨平台框架。 Mat - 图像容器 Mat类用于表示一个多维的单通道或者多通道的稠密数组。能够用来保存实数或复数的向量、矩阵&#xff0c;…

layui多文件上传讲解_Layui 多文件上传 SSH

jsp 页面pageEncoding"UTF-8"%>Insert title here选择多文件文件名大小状态操作开始上传layui.use(upload, function(){var $ layui.jquery,upload layui.upload;//多文件列表示例var demoListView $(#demoList),uploadListIns upload.render({elem: #testLis…

OpenCV:H1.type() == H2.type() H1.depth() == CV_32F

如题&#xff1a; E/cv::error(): OpenCV(4.1.0) Error: Assertion failed (H1.type() H2.type() && H1.depth() CV_32F) in compareHist, file /build/master_pack-android/opencv/modules/imgproc/src/histogram.cpp, line 1936 E/org.opencv.imgproc: imgproc::co…

css 外弧_css 伪类实现弧形

在实现页面五花八门的有特色的ui时&#xff0c;我们有时会遇到要用实现一个弧形&#xff0c;而这样的弧形要怎么实现呢&#xff1f;用图片&#xff1f;不太优雅&#xff0c;这样就要无故多加载一张图片了&#xff0c;这里来说说怎么用css的after伪类来实现弧形。总思路&#xf…

C++期末实践程序设计与数组作为参数的注意事项

目录小表弟发来的求助信号要点代码文件头文件Student.h源文件Student.cppmain.c执行结果c数组特性以及数组做形参的特点数组试验数组特殊性质不允许拷贝和赋值数组是通常被转化成指针使用数组形参多种写法代理模式MVC模式小表弟发来的求助信号 并补充说要5种写法才算过关。 要…

sgm3157功能_SGM3157_SGM3157供应商_价格_Datasheet_pdf资料-IC资料网

SGM31574.5惟 Low Voltage SPDT Analog SwitchSGMICROSG Micro CorpLow Voltage SPDT Analog Switch in 6-Pin SC70SGMICROSG Micro Corp4.5惟 Low Voltage SPDT Analog SwitchSGMICROSG Micro CorpFLAT WASHERS NYLON FIBREetc2List of Unclassifed Manufacturers70 MHz Bandp…

windows 7远程桌面和被远程连接电脑启动远程桌面服务

目录远程桌面连接开启远程桌面服务&#xff08;被连电脑&#xff09;配置启动远程桌面服务远程桌面连接 这部分主要讲解如何通过一台windows 电脑的远程桌面程序连接"远程"电脑桌面。前提是被连的那台电脑已开启远程桌面服务。远程桌面服务开启之后&#xff0c;可以…

desktop docker 无法卸载_关于Docker:Docker – 无法移除死容器

我无法删除死容器&#xff0c;它在重新启动Docker服务后再次出现。docker ps -aCONTAINER ID STATUS11667ef16239 Dead然后docker rm -f 11667ef16239然后&#xff0c;当我运行docker ps -a时&#xff0c;没有Docker容器显示。docker ps -aCONTAINER ID …

git 命令详解和Android Studio代码管理工具

目录前言git命令上传项目一、核心操作二、解决冲突三、情景举例四、查看ssh密钥五、克隆远程项目六、回退某个操作七、和远程分支建立关联八、删除文件九、远程仓储十、多人协作十一、分支策略十二、其他Android Studio代码管理控制前言 相比SVN CVS的管理模式&#xff0c;git…

表单和字都居中_APP 分享 | 6 款黑科技工具,低调收藏,每一款都很强大!

iSlide 简单、高效地制作PPT使用环境: Windows使用要求: Office 2010 及以上版本授权状况: 无广告 有付费功能官网地址: www.islide.ccSlide是一款基于PowerPoint的插件工具,功能十分强大,高效做PPT必备利器一键优化:将PPT中不规则的字体,段落,色彩,参考线…

Android studio gradle task list 不显示问题

问题描述 新电脑安装android studio后&#xff0c;导入工程&#xff0c;各种配置都弄好变更好&#xff0c;出现了如下情况&#xff1a; 之前习惯的gradle task 不在列表中&#xff0c;好不习惯。 正常期望如下&#xff1a; 处理方法 快捷键Ctrl Alt S或者 file -> se…

python flask高级编程之restful_python Flask实现restful api service

一直在用node.js做后端&#xff0c;要逐步涉猎大数据范围&#xff0c;注定绕不过python&#xff0c;因此决定把一些成熟的东西用python来重写&#xff0c;一是开拓思路、通过比较来深入学习python&#xff1b;二是有目标&#xff0c;有动力&#xff0c;希望能持之以恒的坚持下去…

Android Studio Gradle输出信息乱码

在更换android studio 版本之后&#xff0c;一般windows 版本在项目构建过程中&#xff0c;gradle 相关的信息输出&#xff0c;会出现乱码&#xff0c;基本上明知是字符编码的问题&#xff0c;但看着就是不爽&#xff0c;例如下面这的情形&#xff1a; ע: ijЩ&#xfffd;&am…

python tkinter布局混用_python tkinter布局界面如何实现?

当我们自己走入一个互联网窗口里&#xff0c;寻找内容&#xff0c;清晰而明朗&#xff0c;这就是涉及了一个页面布局的知识&#xff0c;不只是一个站点&#xff0c;一个网页&#xff0c;设置是一个窗体都是有清晰的布局&#xff0c;语言的编写&#xff0c;就是为了效率执行而存…

Edge 修改字符编码(详细图文)

Microsoft Edge 版本 97.0.1072.62 (官方内部版本) (64 位) 前言 如下图&#xff0c;在访问页面时出现乱码&#xff0c;而且一直返回的内容编码是UTF-8&#xff0c;但Edge没找快捷的编码方式选择 方法一 Internet Explorer 模式加载 打开Edge浏览器 点击Edge右上角三点 点…