这里我没有说Set是无序的,毕竟说父类set集合无序的,是不对的,这里不说太多,只指出一点,Set父类下包含很多子类,如:hashSet、TreeSet,但treeset却是有序的。
回归博客文章主题,为什么sh说HashSet是无序的?
首先我们看源码解析。
一、创建hashset实例化对象
Set<String> set = new HashSet<String>();
set.add("hello");
set.add("hello");//重复元素
set.add("java");
set.add("world");
System.out.println(set);//[java, world, hello]
二、查看源码
1、源码类头构造
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
2、HashSet集合的主要成员变量
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
/**
* 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<>();
}
3、HashSet集合添加数据
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
三、查看HashMap的put添加数据方式
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
四、总结分析
通过之前分析的hashmap数据增加的源码,可以发现:
1、HashSet集合操作,是将数据值存入至HashMap的key中;
2、hsahmap在保存数据时,顺序是通过计算key的hash值和当前数组长度的 & 运算,计算保存数据的下标位置。所以说set是无须的。
3、由于每次保存数据,存入的是一个共同的值:
private static final Object PRESENT = new Object();
当存在key的hash与数组大小 & 计算到的值存在数组中时,则会进行新的值的覆盖,所以说set是不重复的。