ArrayList和HashSet的Contains()方法

 首先来看一道笔试题:

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

下面分析为什么,我们先看看JDK中ArrayList的方法contains()的源代码:

public boolean contains(Object o) {

      return indexOf(o) >= 0;

 }

其中调用了indexOf(),我们接着看,

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 方法的常规协定:相同的对象必须具有相等的哈希码。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值