来源: 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. 大众点评cat系统的搭建笔记

    项目地址:https://github.com/dianping/cat 编译步骤: 这个项目比较另类,把编译需要的jar包,单独放在git分支mvn-repo里了,而且官方文档里给了一个错误的命令提 ...

  2. [LeetCode] House Robber III 打家劫舍之三

    The thief has found himself a new place for his thievery again. There is only one entrance to this a ...

  3. [LeetCode] Inorder Successor in BST 二叉搜索树中的中序后继节点

    Given a binary search tree and a node in it, find the in-order successor of that node in the BST. No ...

  4. [LeetCode] Shortest Palindrome 最短回文串

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  5. [LeetCode] Insert Interval 插入区间

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...

  6. POI导出Excel并下载

    首先在pom.xml添加jar包: <!-- 导出excel --> <dependency> <groupId>org.apache.poi</groupI ...

  7. [基础] Array.prototype.indexOf()查询方式

    背景 最近在看Redux源码,createStore用于注册一个全局store,其内部维护一个Listeren数组,存放state变化时所有的响应函数. 其中store.subscribe(liste ...

  8. Java学习笔记(四)

    字符串 字符串应用主要分为String类操作与字符串生成器 在程序中频繁的进行附加字符串则使用字符串生成器StringBuilder 数组 概述 数组是具有相同数据类型的一组数据的集合 数组创建 先声 ...

  9. sql分页操作

    看到了网上关于分页的讲解  对最快的分页语句做了测试 还别说速度真快 总共6w条数据 速度确实so 快 前提是id是主键 或者是索引 declare @page int;--页数 declare @P ...

  10. MVC中得到成员元数据的Description特性描述信息公用方法

    #region 从类型成员获取指定的Attribute T特性集合 /// <summary> /// 从类型成员获取指定的Attribute T特性集合 /// </summary ...