HashSet源代码:
这里以Hashset为主要例子

从以上的源代码可以看出HashSet中真正管理元素的是 private transient HashMap<E,Object> map;并且HashSet的元素是存储在HashMap中的key中的,了解HashMap的人知道key是不能重复的。
HashSet的addAll方法:
下面通过一个例子来debug HashSet的add方法的具体实现

上述代码很容易看出,先在构造的时候就加入了hello,world,java这三个元素,之后又通过addAll方法将元素重新添加一遍(addAll实际是循环add)。debug发现进入了AbstractCollection的addAll

继续debug,画红线的add是由HashSet的add方法完成的。
PRESENT在图一中有,是object实例,实际中是不需要管理的。

一些简单的实验:

在AbstractCollection的addAll方法中modified一开始是false,只有成功add一次才会变成true,而返回的结果是由map put的返回值与null比较所得(map.put(e,PRESENT)==null;)。

从返回结果可以看出addAll没有一次是add成功的,这也证实了set没有元素是重复的。最后set输出也只有一组hello,world,java。
补充一点:HashMap在put时是有返回值的,当key重复时会返回value,否则返回null(可以看源码)。

网友评论