JavaSet的源码分析

Java中,set能保证列表中元素唯一,map就是用来key-value用的东西。

先看Set。

首先Set是个接口,最常见的实现有HashSet,LinkedHashSet,和同步Set。

看HashSet的源码,其他应该类似(只是加上了特定功能,比如使用链表、加上同步机制等)。

public class HashSet<E> extends AbstractSet<E>
  implements Set<E>, Cloneable, Serializable
{
  static final long serialVersionUID = -5024744406713321676L;
  private transient HashMap<E, Object> map;
  private static final Object PRESENT = new Object();

  public HashSet()
  {
    this.map = new HashMap();
  }
一目了然的是,HashSet组合了一个HashMap通过对HashMap的操作来实现哈希set。

hashset的add操作如下:

  public boolean add(E paramE)
  {
    return (this.map.put(paramE, PRESENT) == null);
  }
通过在hashmap中把要放到set中的元素作为key,静态变量present(Object类型)作为value,来为hashset添加元素。

同理,hashset的remove操作也就是对map的操作了。

需要有一点注意到的是,set是如何保证内部的对象唯一性的(当然,也是靠hashmap实现的),怎么感觉像是废话  =。=

hashmap实现唯一性的代码如下:

  public V put(K paramK, V paramV)
  {
    if (paramK == null)
      return putForNullKey(paramV);
    int i = hash(paramK.hashCode());
    int j = indexFor(i, this.table.length);
    for (Entry localEntry = this.table[j]; localEntry != null; localEntry = localEntry.next)
      if (localEntry.hash == i)
      {
        java.lang.Object localObject1;
        if (((localObject1 = localEntry.key) == paramK) || (paramK.equals(localObject1)))
        {
          java.lang.Object localObject2 = localEntry.value;
          localEntry.value = paramV;
          localEntry.recordAccess(this);
          return localObject2;
        }
      }
    this.modCount += 1;
    addEntry(i, paramK, paramV, j);
    return null;
  }
其中粗体标注了检测要添加的元素是否在map中的操作。这里用到了hashcode和equals的作用。 hashcode在之前的文中已经提到过,是为了减少对对象的比较复杂度而设置的。这里遍历了map中所有的元素。

  transient Entry[] table;
上面粗体还提到了table属性。这里是维护的Entry的数组,同其他列表一样,数组大小会自动增长:不过奇怪的是,这里使用了 2147483647这个数字,不知道那个if判断是做什么用的,求指点

  void resize(int paramInt)
  {
    Entry[] arrayOfEntry1 = this.table;
    int i = arrayOfEntry1.length;
    if (i == 1073741824)
    {
      this.threshold = 2147483647;
      return;
    }
    Entry[] arrayOfEntry2 = new Entry[paramInt];
    transfer(arrayOfEntry2);
    this.table = arrayOfEntry2;
    this.threshold = (int)(paramInt * this.loadFactor);
  }





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值