ArrayList和HashSet的Contains()方法(转)
来源: 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()方法(转)的更多相关文章
- 【Java必修课】ArrayList与HashSet的contains方法性能比较(JMH性能测试)
1 简介 在日常开发中,ArrayList和HashSet都是Java中很常用的集合类. ArrayList是List接口最常用的实现类: HashSet则是保存唯一元素Set的实现. 本文主要对两者 ...
- Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题
Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...
- Java中如何克隆集合——ArrayList和HashSet深拷贝
编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法.需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味 ...
- 【转】Java如何克隆集合——深度拷贝ArrayList和HashSet
原文网址:http://blog.csdn.net/cool_sti/article/details/21658521 原英文链接:http://javarevisited.blogspot.hk/2 ...
- 浅谈Java语言中ArrayList和HashSet的区别
Java语言中ArrayList和HashSet的区别 2019-04-10 13:22:49 一.基本区别 首先一起看个实例,其代码如下: package com.MrZ_baby.com; i ...
- 用HashSet的add方法谈hashcode和equals方法重写
本文主要通过用HashSet的add方法讲一下hashCode和equals方法重写.错误的地方望指正. 1.了解HashSet的add方法 了解一个方法的好办法是看源码,所以先看源码 private ...
- java中把list列表转为arrayList以及arraylist数组截取的简单方法
java中把list列表转为arrayList以及arraylist数组截取的简单方法 package xiaobai; import java.util.ArrayList; import java ...
- Java学习笔记27(集合框架一:ArrayList回顾、Collection接口方法)
集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组的区别: 1.数组的长度是固定的,集合的长度是可变的 2.集合中存储的元素必须是引用类型数据 对ArrayList集合的回顾 示例 ...
- ArrayList的add(E e)方法与扩容
ArrayList是Java开发中经常用到的集合类,它是List接口的实现类,具有很高的查询性能,但不是线程安全的.本文主要讲述了ArrayList的add(E e)方法及该方法中涉及到的容量扩容技术 ...
随机推荐
- Redis集群~windows下搭建Sentinel环境及它对主从模式的实际意义
回到目录 关于redis-sentinel出现的原因 Redis集群的主从模式有个最大的弊端,就是当主master挂了之前,它的slave从服务器无法提升为主,而在redis-sentinel出现之后 ...
- php伪静态--隐藏地址实际路径方法
1.修改Apache配置文件:httpd.conf #LoadMoule rewrite_module modules/mod_rewrite.so --去掉注释 2.查找httpd.conf 中的 ...
- Android国际化--I18N
在res下创建对应国家的环境的目录如:values-zh,values-en,然后在对应的目录下将对应的字符串翻译成对应国家的语言即可.
- vs2017 rc 离线安装包制作
vs2017 rc 离线安装包制作 1.下载在线安装包:https://aka.ms/vs/15/release/vs_Enterprise.exe 2.制作离线安装包: vs_Enterprise. ...
- UIButton快速点击,只执行最后一次
button快速点击时,会导致,同一动作执行多次,常用解决办法: 第一种方法:推荐 //取消执行 [[self class] cancelPreviousPerformRequestsWithTarg ...
- IntelliJ运行下载的Servlet时报错 Error running Tomcat 8.5.8: Unable to open debugger port (127.0.0.1:49551): java.net.SocketException
学习Java Servlet时,从Wrox上下载了示例代码,准备run/debug时发现以下错误: Error running Tomcat 8.5.8: Unable to open debugge ...
- 5 Django系列之通过list_display展示多对多与外键内容在admin-web界面下
list_display展示多对多关系的内容 表结构关系 表一 class Server(models.Model): asset = models.OneToOneField('Asset') cr ...
- C# .Net :Excel NPOI导入导出操作教程之将Excel文件读取并写到数据库表,示例分享
using (FileStream fileReader = File.OpenRead(@"C:\Users\Administrator\Desktop\112.xls")) ...
- mybatis : trim标签, “等于==”经验, CDATA标签 ,模糊查询CONCAT,LIKE
一.My Batis trim标签有点类似于replace效果. trim 属性, prefix:前缀覆盖并增加其内容 suffix:后缀覆盖并增加其内容 prefixOverrides:前缀判断的条 ...
- Access-Control-Allow-Origin与跨域问题
在某域名下使用Ajax向另一个域名下的页面请求数据,会遇到跨域问题.另一个域名必须在response中添加 Access-Control-Allow-Origin 的header,才能让前者成功拿到数 ...