来源: ArrayList和HashSet的Contains()方法

笔试题:

package com.champion.test.exam;

import java.util.ArrayList;
import java.util.HashSet; public class Foo {
int value; Foo(int value) {
this.value = value;
} public boolean equals(Object obj) { if (obj instanceof Foo) { Foo foo = (Foo) obj; return value == foo.value; } else { return false; } } /**
* public int hashCode() {
*
* return this.value;
*
* }
*
*/ public static void main(String... args) { ArrayList list = new ArrayList(); HashSet set = new HashSet(); Foo f1 = new Foo(1); Foo f2 = new Foo(1); list.add(f1); set.add(f2); Foo f3 = new Foo(1); Foo f4 = new Foo(1); System.out.println(list.contains(f3) + "," + set.contains(f4)); }
}

答案:true,false 打开注释后,结果为:true ,true

主要原因为:

ArrayList和HashSet 的contains的 底层的实现不同

ArrayList的contains

public boolean contains(Object o) {  

  return indexOf(o) >= 0;  

} 

public int indexOf(Object o) {  

if (o == null) {  

   for (int i = 0; i < size; i++)  

  if (elementData[i]==null)  

  return i;//如果o为空且集合中i位置处也为空,返回i  

   } else {  

   for (int i = 0; i < size; i++)  

  if (o.equals(elementData[i]))  

  return i;//如果o不为空,且集合中i位置对象equals对象o,返回i  

   }  

   return -1;//否则返回-1  

}

所以,因为list中有对象f1,而f1.equals(f3)为true,所以执行indexOf()方法返回0,执行contains()返回true;

HashSet中contains()

public boolean contains(Object o) {  

  return map.containsKey(o);  

}  

public boolean containsKey(Object key) {  

   return getEntry(key) != null;  

}  

final Entry<K,V> getEntry(Object key) {  

int hash = (key == null) ? 0 : hash(key.hashCode());  

for (Entry<K,V> e = table[indexFor(hash, table.length)];  

 e != null;  

 e = e.next) {  

Object k;  

if (e.hash == hash &&  

((k = e.key) == key || (key != null && key.equals(k))))  

return e;  

}  

   return null;  

 }

由于Foo类中重写了equals()而没有重写hashCode()方法,所以会执行父类Object 中的 hashCode 方法,(会针对不同的对象返回不同的整数,具体是将该对象的内部地址转换成一个整数来实现的),由于f2和f4内存地址不同,所以hashcode也不同,所以执行getEntry()方法返回null,执行containsKey返回false,当然的执行contains()也会返回false;

综上所述:对于一个类重写了equals()方法后,重写它的hashCode()方法是必要的,以维护 hashCode 方法的常规协定:相同的对象必须具有相等的哈希码。

ArrayList和HashSet的Contains()方法(转)的更多相关文章

  1. 【Java必修课】ArrayList与HashSet的contains方法性能比较(JMH性能测试)

    1 简介 在日常开发中,ArrayList和HashSet都是Java中很常用的集合类. ArrayList是List接口最常用的实现类: HashSet则是保存唯一元素Set的实现. 本文主要对两者 ...

  2. Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

    Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...

  3. Java中如何克隆集合——ArrayList和HashSet深拷贝

    编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法.需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味 ...

  4. 【转】Java如何克隆集合——深度拷贝ArrayList和HashSet

    原文网址:http://blog.csdn.net/cool_sti/article/details/21658521 原英文链接:http://javarevisited.blogspot.hk/2 ...

  5. 浅谈Java语言中ArrayList和HashSet的区别

    Java语言中ArrayList和HashSet的区别 2019-04-10   13:22:49 一.基本区别 首先一起看个实例,其代码如下: package com.MrZ_baby.com; i ...

  6. 用HashSet的add方法谈hashcode和equals方法重写

    本文主要通过用HashSet的add方法讲一下hashCode和equals方法重写.错误的地方望指正. 1.了解HashSet的add方法 了解一个方法的好办法是看源码,所以先看源码 private ...

  7. java中把list列表转为arrayList以及arraylist数组截取的简单方法

    java中把list列表转为arrayList以及arraylist数组截取的简单方法 package xiaobai; import java.util.ArrayList; import java ...

  8. Java学习笔记27(集合框架一:ArrayList回顾、Collection接口方法)

    集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组的区别: 1.数组的长度是固定的,集合的长度是可变的 2.集合中存储的元素必须是引用类型数据 对ArrayList集合的回顾 示例 ...

  9. ArrayList的add(E e)方法与扩容

    ArrayList是Java开发中经常用到的集合类,它是List接口的实现类,具有很高的查询性能,但不是线程安全的.本文主要讲述了ArrayList的add(E e)方法及该方法中涉及到的容量扩容技术 ...

随机推荐

  1. [LeetCode] Pascal's Triangle II 杨辉三角之二

    Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3,Return [1,3, ...

  2. AppBoxPro - 细粒度通用权限管理框架(可控制表格行内按钮)源码提供下载

    特别声明: 提供的源代码已经包含了 AppBoxPro 的全部源代码,用 VS2012 打开项目后,直接 Ctrl+F5 可以运行起来(默认使用VS自带的LocalDB数据库). FineUIPro是 ...

  3. LTE中的各种ID含义

    原文链接:http://www.hropt.com/ask/?q-7128.html ECI (28 Bits) = eNB ID(20 Bits) + Cell ID(8 Bits) 换成16进制就 ...

  4. bootstrop 日期控件 datepicker被弹出框dialog覆盖的解决办法

    筒子们在使用bootstrap的日期控件(datepicker , 现在官网提供的名称叫 datetimepicker)时可能会遇到如上图的问题这是啥原因造成的呢? 答案很简单时输出的优先级造成的(z ...

  5. eclipse报错“Undefined variable from import: ...”解决方案

    环境 eclipse + pydev2.8.2 + python 3.5.1/python 2.7.11 + wxpython3.0 出现原因:原先默认解释器设置为python2,重装了pydev之后 ...

  6. WEB开发最佳实践

    linux命令 man ls:显示ls的命令详情,man命令可以查具体的命令详情

  7. Oracle 查询表中字段里数据是否有重复

    1.查找单个字段 select 字段名,count(*) from table group by 字段名 having count(*) > 1 2.查找组合字段: SELECT TEST_NA ...

  8. zlib-1.2.7/libpng-1.5.9 instead of zlib-1.2.8/libpng-1.6.6

    The reason for the failure apparently appears to be version incompatibility, partly may be due to li ...

  9. Premiere使用整理

    整理部分自己在使用Premiere CC中遇到的问题和注意点. 1. 新建序列 若是录屏文件,可选择已加入到项目中的视频文件,点击 文件-新建-来自剪辑的序列. 2. 新建字幕 用于在视频中添加文字. ...

  10. 一些不太常见但很有用的java类

    java.util.concurrent.CopyOnWriteArrayList CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性.所以如果你希望写入的的数据,马上能读到 ...