HashSet源码笔记之普通增删查改
上代码:
构造方法
HashSet hashSet = new HashSet();
看HashSet的构造方法,不看不知道,一看吓一跳,这货就是杜鹃鸟借窝下蛋,当然也有可能是隔壁老王留下的星火;
/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
没错你没看错这玩意里面是一个HashMap,我们来回顾一下HashSet的特点:不允许集合中有重复的值,允许有null的存在;
在看看HashMap的特点:键不可以有重复值,允许有null的存在,这一对比这特么不就是HashMap的健吗,而且我们在注意一下我们获取HashMap健集合的时候,获取的也是一个Set集合;不过这两货到底有啥爱恨纠葛,我们往下看;
添加方法
来看看添加方法:
HashSet hashSet = new HashSet();
hashSet.add(null);
System.out.println(hashSet);
看之前我们来先想一下,既然它的底层是一个HashMap,那么它添加接口应该就是调用HashMap的put方法然后讲值作为HashMap的key,值的话应该是一个null,毕竟HashMap还是允许null作为值的,带着这个猜测往下看,
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
将指定的元素添加到此集合(如果尚未存在)。 更正式地,将指定的元素e添加到此集合,如果此集合不包含元素e2 ,使得(e==null ? e2==null : e.equals(e2)) 。 如果该集合已经包含该元素,则该呼叫将保持不变,并返回false 。
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
emmm这货果然是用的put方法,然后以传入的值作为键,但是它的值却不是空,而是一个PRESENT对象
这是为什么呢?看看注释,HashSet添加一个元素,如果是第一次添加这个元素,那么会返回true,如果之前已近添加过该元素则返回false,再结合hashMap的put方法,put方法是添加一个元素返回旧的元素,如果第一次添加则返回null,原来如此,这就不难理解为什么要以一个对象作为值了.put方法会把旧值返回,如果我们以Null作为值,这样就没办法判断该元素是新增元素还是该元素以前就存在了
修改方法
抱歉没有修改方法,
查询方法
没下标你拿啥查,拿元素?你都知道元素了你还查毛线;
删除方法:
想啥呢这个方法肯定有:不想了这个方法肯定是调用HashMap的remove方法,(HashMap的remove方法传入要移除的 返回对应key的value),然后在结合一下HashSet的remove方法**(删除成功返回true ,失败返回false)**推导一下代码,我们在添加元素的时候将key作为建,PRESENT作为值,所以调动HashMap的remove方法只要执行成功返回的肯定是PRESENT,然后HashSet的remove方法(删除成功返回true ,失败返回false),得 map.remove(key) == PRESENT 然后返回:
看源码:
/**
* Removes the specified element from this set if it is present.
* More formally, removes an element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>,
* if this set contains such an element. Returns <tt>true</tt> if
* this set contained the element (or equivalently, if this set
* changed as a result of the call). (This set will not contain the
* element once the call returns.)
*
* @param o object to be removed from this set, if present
* @return <tt>true</tt> if the set contained the specified element
*/
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}