8.Set接口
Set 接口也继承 Collection 接口,是无序,不可重复的集合。没有索引,最多包含一个null,不能使用普通for循环遍历。
无序(取决hash)是取出顺序与添加顺序不一致,但是多次遍历后取出顺序是一致的。
public interface Set<E> extends Collection<E> {}
9.HashSet
- 底层是HashMap
- 值存放于HashMap的key上,value统一为PRESENT
Set set = new HashSet();set.add("jack"); // 1. 添加成功set.add("jack"); // 2. 添加失败set.add(new Person("jack")); // 3. 添加成功set.add(new Person("jack")); // 4. 添加成功set.add(new String("tom")); // 5. 添加成功set.add(new String("tom")); // 6. 添加失败
构造
public HashSet() {
map = new HashMap<>();
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
add(E e):具体分析在HashMap的put方法
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object(); //占位
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
10.LinkedHashSet
继承自HashSet,且直接实现了 Set 接口。
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable
- 底层是LinkedHashMap
- 根据元素hashCode中的值决定元素的存储位置,同时使用双向链表维护元素的次序,使得元素看起来插入是有序的
构造
public LinkedHashSet() {
super(16, .75f, true);//调用父类 HashSet 的构造器
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor); // 16 0.75
}
add()
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
11.TreeSet
- TreeSet 可以用于排序,底层是用 TreeMap 实现
- 当使用无参构造器创建 TreeSet 是按照默认key自然排序
- 可以使用指定排序规则的构造器使 TreeSet 按照指定规则排序
// 这里使用 Comparator接口类型的实现类 作为参数的构造器,这里定义了排序规则
TreeSet<String> treeSet = new TreeSet<>((s1, s2) -> s1.compareTo(s2));
treeSet.add("a");
treeSet.add("b");
treeSet.add("c");
构造
public TreeSet() {
this(new TreeMap<E,Object>());
}
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
add()
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
