详述ArrayList类contains方法
一、源码:
//源码1
public boolean contains(Object o) {return indexOf(o) >= 0;}
//源码2
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++)if (o.equals(elementData[i]))//语句2return i;}
注:elementData[i]代表集合里面已经有的元素,o为contains方法传入的参数
二、contains方法对不同类的数据类型执行过程分析
1、String类
①代码举例:
ArrayList<String> names = new ArrayList<String>();
names.add("Jim");
System.out.println(names.contains("Jim"));//语句1
②分析:
当执行到语句1的时候首先进入源码1,此时的o为Jim,继续执行代码到源码2,执行indexOf(Object o)方法,该方法先判断o是否为空,显然不是,则执行else里面的语句,通过o去调用equals方法与集合里面的元素去比较,看是否存在一样的元素,而这里的o是一个上转型对象,相当于Object o = new String("Jim"),会呈现多态,因此运行时执行的是String类中重写的equals方法,String类中重写的equals方法比较的是内容是否相同,都是Jim,因此输出为true
2、包装类
①代码举例:
ArrayList<Integer> ages = new ArrayList<Integer>();
ages.add(12);
System.out.println(ages.contains(12));//语句2
②分析:
当执行到语句2的时候首先进入源码1,此时的o为12,继续执行代码到源码2,执行indexOf(Object o)方法,该方法先判断o是否为空,显然不是,则执行else里面的语句,通过o去调用equals方法与集合里面的元素去比较,看是否存在一样的元素,而这里的o是一个上转型对象,相当于Object o = new Integer(12),会呈现多态,因此运行时执行的是Integer包装类中重写的equals方法,Integer类中重写的equals方法比较的是数值是否相同,都是12,因此输出为true
3、自定义类类型数据
①代码举例:
ArrayList<Student> students = new ArrayList<Student>();
students.add(new Student("111"));//语句4
System.out.println(students.contains(new Student("111")));//语句3
②分析:
a.重写equals方法前
当执行到语句3的时候首先进入源码1,此时的o为new Student("111"),继续执行代码到源码2,执行indexOf(Object o)方法,该方法先判断o是否为空,显然不是,则执行else里面的语句,通过o去调用equals方法与集合里面的元素去比较,看是否存在一样的元素,而这里的o是一个上转型对象,相当于Object o = new Student("111"),会呈现多态,但此时Student类没有重写equals方法,因此运行时执行的是Object类的equals方法,Object类的equals方法比较的是地址是否相同,而这里的是两个不同的Student对象,地址显然是不同的,因此输出为false,但是我们的目的是比较内容是否相同,因此对于自定义类类型数据需要根据需要去重写equals方法,重写的方法如下所示
b.重写equals方法后
代码举例:
public class Student {private String id;public Student(String id) {this.id = id;}@Overridepublic boolean equals(Object obj) {//obj代表集合中已有的元素,语句5Student stu =(Student)obj;//语句6return this.id.equals(stu.id);//语句7}}
分析:
当执行到语句3的时候首先进入源码1,此时的o为new Student("111"),继续执行代码到源码2,执行indexOf(Object o)方法,该方法先判断o是否为空,显然不是,则执行else里面的语句,通过o去调用equals方法与集合里面的元素去比较,看是否存在一样的元素,而这里的o是一个上转型对象,相当于Object o = new Student("111"),会呈现多态,此时执行的是Student类中重写的equals方法,如以上代码所示,此时语句5的obj是语句4所存入的Student对象,语句7的this是语句3所创造的那个Student对象(因为是该对象调用该Student中的equals方法)。我们的目的是比较内容是否相同(此处为id),因此通过this.id和stu.id得到内容,此时的id为字符串,因此语句7的执行的是String类中的equals方法。显然内容是相同的,因此输出true。值得注意的是:语句6为什么要这样做?答案很简单,此时的obj为上转型对象,而id是Student这个子类新增的属性,上转型对象要调用子类新增的属性必须下转型,因此有了语句6。
c.代码改进——instanceof
代码举例:
ArrayList<Object> students = new ArrayList<Object>();//语句8
students.add(new String());//语句9
System.out.println(students.contains(new Student("111")));//语句10
分析:
如语句8所示,如果集合中可以存入任意类型的数据,当通过语句9存入一个String类的对象,当执行到语句6的时候,此时的obj为String类创建的对象,String类和Student类没有任何关系,不能够下转型,因此会报错,为了避免这种情况,需要通过使用instanceof到达只有Student类创建的对象才进行下转型,改进后的equals方法如下:
@Override
public boolean equals(Object obj) {//obj代表集合中已有的元素if (obj instanceof Student) {//集合中未必所有的元素都是Student类创建的对象Student stu =(Student)obj;return this.id.equals(stu.id);}return false;
}
详述ArrayList类contains方法相关推荐
- 详述ArrayList类中的contains方法
详述ArrayList类中的contains方法 一.contains方法的参数是String类型 import java.util.ArrayList;public class Test {publ ...
- 详述ArrayList的contains方法
ArrayList的contains方法,有以下三种类型: 形式一: 查找的字符不为null时,看如下代码: import java.util.ArrayList;public class Work ...
- 详述ArrayList类中的contains()方法及原理
contains()方法可以用来判断集合中是否含有某元素,若有则返回true,没有则返回false. contains()源码: public boolean contains(Object o) { ...
- ArrayList类contains方法实现原理
以ArrayList集合示例 思考:contains方法如何执行? public static void main(String [] args){List<String> list=ne ...
- ArrayList中contain方法
详述ArrayList中contains方法 JDK源码: //contains方法 public boolean contains(Object o) {return indexOf(o) > ...
- 多线程下ArrayList类线程不安全的解决方法及原理
多线程下ArrayList类线程不安全的解决方法及原理 参考文章: (1)多线程下ArrayList类线程不安全的解决方法及原理 (2)https://www.cnblogs.com/fangting ...
- Lession11 集合和泛型(ArrayList方法、Arraylist类、ArrayList添加对象、ArrayList长度、HashTable类、Hashtable类练习-----)
目录 ArrayList方法: ArrayList添加对象: Arraylist类: ArrayList长度: HashTable类: Hashtable类练习: IComparable泛型接口排序: ...
- 写一个ArrayList类的动态代理类
动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实,代理对象对客户隐藏了实际对象.动态代理可以对请求进行其他的一些处理,在不允许直接访问某些类,或需要对访问做一些特殊处理等,这时候可以考虑 ...
- 工具类的方法怎么引用_Hutool中那些常用的工具类和方法
Hutool是一个Java工具包,它帮助我们简化每一行代码,避免重复造轮子.如果你有需要用到某些工具方法的时候,不妨在Hutool里面找找,可能就有.本文将对Hutool中的常用工具类和方法进行介绍. ...
- 【EventBus】事件通信框架 ( 订阅方法注册 | 注册 事件类型 - 订阅类 + 订阅方法 到指定集合 | 取消注册 数据准备 )
文章目录 一.注册订阅方法 二.完整代码示例 一.注册订阅方法 订阅方法注册的过程就是将 订阅方法参数类型 和 订阅类 + 订阅方法 封装类 , 保存到 Map<Class<?>, ...
最新文章
- docker仓库harbor搭建
- 苹果手机怎么编辑word文档_原创首发:编辑和修改PDF文档,将PDF转换为WORD技巧...
- 华为呼叫中心解决方案学习笔记一(方案概述)
- [react] 说说你喜欢react的原因是什么?它有什么优缺点?
- java前言_Java Web前言
- Linux内核vmalloc原理与实现
- Spring的ID增长器使用示例(MySql数据库)
- java测试步骤_java测试框架的方法
- java生成点阵图_点阵字库在JAVA中的实现
- 2018.8.2课堂笔记
- c51单片机矩阵键盘1602计算器_基于矩阵键盘1602液晶屏的简易计算器的设计系统-电子信息科学与技术课程设计说明书.doc...
- 《灰色预测(GM)的MATLAB实现》
- python实战-HTML形式爬虫-批量爬取电影下载链接
- 基于iSensor的MT9M001C12STM传感器调试总结
- Paper Note - SLEUTH:基于COTS审计数据的实时攻击场景重构
- matlab中的sym
- 《从程序猿到项目经理》读后感-直率
- 计算机存储程序错误检验,内存错误怎么办?内存错误的修复与检测方法介绍
- 如何下载谷歌地球历史地图
- TwinCAT3之Ads通讯——1、控制器和控制器间通讯