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)方法及该方法中涉及到的容量扩容技术 ...
随机推荐
- [LeetCode] Climbing Stairs 爬梯子问题
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- Oracle 表和表数据恢复
1. 表恢复 对误删的表,只要没有使用 purge 永久删除选项,那么基本上是能从 flashback table 区恢复回来的. 数据表和其中的数据都是可以恢复回来的,记得 flashback ta ...
- 将HTML5封装成android应用APK文件的几种方法
越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...
- 控制反转(IOC)
对于很多大中型项目为了实现解耦都用到了控制反转. 常用的控制反转有unity,autoface,spring.Net 使用它们的目的归根结底就一个:避免了直接new一个对象. 今天抽时间将三种控制反转 ...
- java sound初探
网上关于java sound的正规资源讲解的非常好,本文不再给出示例,主要提供一些好的资源,并说说我的一些理解,用于形成对java sound的整体认识. 一.几个词汇 TTS:text-to-spe ...
- Android系统中应用的安装和卸载的监听
一.创建一个类继承BroadcastReceiver并且复写onReceive的方法 public class AppStateReceiver extends BroadcastReceiver { ...
- Spring_跨项目读取properties文件
应用背景:工程中有40~50个项目,分为4个模块,分别是核心模块.服务接口模块.服务实现模块.Web模块.其它模块(包括消息队列.quartz任务等).工程中很多配置项都是多个项目共有调用的,所以单独 ...
- C#定义类型转化 及 格式化字符串
operator 关键字 operator 关键字用来重载内置运算符,或提供类/结构声明中的用户定义转换.它可以定义不同类型之间采用何种转化方式和转化的结果. operator用于定义类型转化时可采用 ...
- --关于null在oracle数据库中是否参与计算,进行验证,
--关于null在oracle数据库中是否参与计算,进行验证,with td as (select null id,1 name from dual ),td1 as ( select null id ...
- 安装了ruby后怎么安装sass
在命令行中输入 ruby -v 查看版本号 先移除默认的https://rubygems.org源,命令为gem sources --remove https://rubygems.org/,按回车 ...