java集合框架之HashSet
参考http://how2j.cn/k/collection/collection-hashset/364.html#nowhere
元素不能重复
Set中的元素,不能重复
重复判断标准是:
首先看hashcode是否相同
如果hashcode不同,则认为是不同数据
如果hashcode相同,再比较equals,如果equals相同,则是相同数据,否则是不同数据
package collection; import java.util.HashSet; public class TestCollection { public static void main(String[] args) { HashSet<String> names = new HashSet<String>(); names.add("gareen"); System.out.println(names); //第二次插入同样的数据,是插不进去的,容器中只会保留一个 names.add("gareen"); System.out.println(names); } }
没有顺序
Set中的元素,没有顺序。
严格的说,是没有按照元素的插入顺序排列
HashSet的具体顺序,既不是按照插入顺序,也不是按照hashcode的顺序。
遍历
Set不提供get()来获取指定位置的元素
所以遍历需要用到迭代器,或者增强型for循环
package collection; import java.util.HashSet; import java.util.Iterator; public class TestCollection { public static void main(String[] args) { HashSet<Integer> numbers = new HashSet<Integer>(); for (int i = 0; i < 20; i++) { numbers.add(i); } //Set不提供get方法来获取指定位置的元素 //numbers.get(0) //遍历Set可以采用迭代器iterator for (Iterator<Integer> iterator = numbers.iterator(); iterator.hasNext();) { Integer i = (Integer) iterator.next(); System.out.println(i); } //或者采用增强型for循环 for (Integer i : numbers) { System.out.println(i); } } }
HashSet和HashMap的关系
通过观察HashSet的源代码
可以发现HashSet自身并没有独立的实现,而是在里面封装了一个Map.
HashSet是作为Map的key而存在的
而value是一个命名为PRESENT的static的Object对象,因为是一个类属性,所以只会有一个。
package collection; import java.util.AbstractSet; import java.util.HashMap; import java.util.Iterator; import java.util.Set; public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { //HashSet里封装了一个HashMap private HashMap<E,Object> map; private static final Object PRESENT = new Object(); //HashSet的构造方法初始化这个HashMap public HashSet() { map = new HashMap<E,Object>(); } //向HashSet中增加元素,其实就是把该元素作为key,增加到Map中 //value是PRESENT,静态,final的对象,所有的HashSet都使用这么同一个对象 public boolean add(E e) { return map.put(e, PRESENT)==null; } //HashSet的size就是map的size public int size() { return map.size(); } //清空Set就是清空Map public void clear() { map.clear(); } //迭代Set,就是把Map的键拿出来迭代 public Iterator<E> iterator() { return map.keySet().iterator(); } }