一、源码:

//源码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方法相关推荐

  1. 详述ArrayList类中的contains方法

    详述ArrayList类中的contains方法 一.contains方法的参数是String类型 import java.util.ArrayList;public class Test {publ ...

  2. 详述ArrayList的contains方法

    ArrayList的contains方法,有以下三种类型: 形式一: 查找的字符不为null时,看如下代码: import java.util.ArrayList;public class Work ...

  3. 详述ArrayList类中的contains()方法及原理

    contains()方法可以用来判断集合中是否含有某元素,若有则返回true,没有则返回false. contains()源码: public boolean contains(Object o) { ...

  4. ArrayList类contains方法实现原理

    以ArrayList集合示例 思考:contains方法如何执行? public static void main(String [] args){List<String> list=ne ...

  5. ArrayList中contain方法

    详述ArrayList中contains方法 JDK源码: //contains方法 public boolean contains(Object o) {return indexOf(o) > ...

  6. 多线程下ArrayList类线程不安全的解决方法及原理

    多线程下ArrayList类线程不安全的解决方法及原理 参考文章: (1)多线程下ArrayList类线程不安全的解决方法及原理 (2)https://www.cnblogs.com/fangting ...

  7. Lession11 集合和泛型(ArrayList方法、Arraylist类、ArrayList添加对象、ArrayList长度、HashTable类、Hashtable类练习-----)

    目录 ArrayList方法: ArrayList添加对象: Arraylist类: ArrayList长度: HashTable类: Hashtable类练习: IComparable泛型接口排序: ...

  8. 写一个ArrayList类的动态代理类

    动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实,代理对象对客户隐藏了实际对象.动态代理可以对请求进行其他的一些处理,在不允许直接访问某些类,或需要对访问做一些特殊处理等,这时候可以考虑 ...

  9. 工具类的方法怎么引用_Hutool中那些常用的工具类和方法

    Hutool是一个Java工具包,它帮助我们简化每一行代码,避免重复造轮子.如果你有需要用到某些工具方法的时候,不妨在Hutool里面找找,可能就有.本文将对Hutool中的常用工具类和方法进行介绍. ...

  10. 【EventBus】事件通信框架 ( 订阅方法注册 | 注册 事件类型 - 订阅类 + 订阅方法 到指定集合 | 取消注册 数据准备 )

    文章目录 一.注册订阅方法 二.完整代码示例 一.注册订阅方法 订阅方法注册的过程就是将 订阅方法参数类型 和 订阅类 + 订阅方法 封装类 , 保存到 Map<Class<?>, ...

最新文章

  1. docker仓库harbor搭建
  2. 苹果手机怎么编辑word文档_原创首发:编辑和修改PDF文档,将PDF转换为WORD技巧...
  3. 华为呼叫中心解决方案学习笔记一(方案概述)
  4. [react] 说说你喜欢react的原因是什么?它有什么优缺点?
  5. java前言_Java Web前言
  6. Linux内核vmalloc原理与实现
  7. Spring的ID增长器使用示例(MySql数据库)
  8. java测试步骤_java测试框架的方法
  9. java生成点阵图_点阵字库在JAVA中的实现
  10. 2018.8.2课堂笔记
  11. c51单片机矩阵键盘1602计算器_基于矩阵键盘1602液晶屏的简易计算器的设计系统-电子信息科学与技术课程设计说明书.doc...
  12. 《灰色预测(GM)的MATLAB实现》
  13. python实战-HTML形式爬虫-批量爬取电影下载链接
  14. 基于iSensor的MT9M001C12STM传感器调试总结
  15. Paper Note - SLEUTH:基于COTS审计数据的实时攻击场景重构
  16. matlab中的sym
  17. 《从程序猿到项目经理》读后感-直率
  18. 计算机存储程序错误检验,内存错误怎么办?内存错误的修复与检测方法介绍
  19. 如何下载谷歌地球历史地图
  20. TwinCAT3之Ads通讯——1、控制器和控制器间通讯

热门文章

  1. DTCMS插件的制作实例电子资源管理(二)Admin后台页面编写
  2. Python 学习笔记 (6)—— 读写文件
  3. 进口食品加盟 选择自由自在休闲食品
  4. Keras(六)Autoencoder 自编码 原理及实例 Savereload 模型的保存和提取
  5. nodepad代码格式复制到word发布到博客
  6. Tensorflow自编码器及多层感知机
  7. 自动化测试UI Test, Performance Test, Load Test 总结整理
  8. nodejs - 服务端管理 - PM2
  9. iOS ASI--POST请求
  10. my first d3d application 哈哈哈。