List和Set都继承至Collection()接口,同时继承Iterable(迭代器)接口
List主要的实现类有Vector和ArrayList、LinkedList,特征
1,有序
2,索引查找
3,根据序号找到对应元素
Vector和ArrayList
1,底层是数组
2,支持加入null
3,Vector线程安全,因为有synchronized关键字 ArrayList线程不安全
4,查询快
LinkedList
1,底层是双向链表
2,成员变量first 与 last 指向首尾节点
3,内部类Node对象 有prev next item 分别指向前一个,后一个,自己
4,LinkedList增删快
Set接口主要两个实现类 HashSet和TreeSet
- 不能存放重复的元素, 可以添加一个 null
- set 接口对象存放数据是无序(即添加的顺序和取出的顺序不一致)
- 注意:取出的顺序的顺序虽然不是添加的顺序,但是是固定的
HashSet
1.底层是HashMap
2.可以存放null值,但只有一个null
3.存入与取出顺序不一致,但固定取出顺序
4.不能有重复的元素
5.底层是HashMap,所有的元素其实是作为key值存入HashMap之中
//声明了一个HashMap类型的成员变量
private transient HashMap<E,Object> map;
//成员方法
public HashSet() {
map = new HashMap<>();
}
//add方法 实际存入的元素,是作为key值存入的
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
LinkedHashSet
1,LinkedHashSet底层实际是LinkedHashMap
2,底层是 数组+双向链表+红黑树
3,底层根据元素的hashcode值来决定元素的存储位置,同时使用双向链表维护元素的次序
4,因为是key值,不允许插入重复数据
//构造方法调用父类构造方法,父类是HashSet
public LinkedHashSet() {
super(16, .75f, true);
}
private transient HashMap<E,Object> map;
//父类构造方法
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
//这里map的对象实际是LinkedHashMap 它继承了hashMap,并重写了newNode方法
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
//同时LinkedHashMap重写了HashMap的newNode方法
//这个方法中linkNodeLast会为双向链表的相关head,tail等赋值
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
LinkedHashMap.Entry<K,V> p =
new LinkedHashMap.Entry<K,V>(hash, key, value, e);
linkNodeLast(p);
return p;
}
TreeSet
TreeSet的底层是TreeMap
构造方法中传入的就是TreeMap对象
public TreeSet() {
this(new TreeMap<E,Object>());
}
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
TreeSet的元素是必定有序的
这与其内部构造也有关系,如,其add方法调用的就是map的put方法
TreeMap的put方法传入的key则必须实现Comparable接口并重写compareTo方法
并且在put方法中调用其compareTo对比
final int compare(Object k1, Object k2) {
return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
: comparator.compare((K)k1, (K)k2);
}
TreeMap元素的存放数据结构为红黑树结构
存放元素为TreeMap.Entry内部类
class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK;
/**
* Make a new cell with given key, value, and parent, and with
* {@code null} child links, and BLACK color.
*/
Entry(K key, V value, Entry<K,V> parent) {
this.key = key;
this.value = value;
this.parent = parent;
}
TreeMap的put方法根据key值对比,从根节点依次遍历所有元素
直到key相等return,或按照大小将其添加到最后节点的left或right
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
最后调用fixAfterInsertion(e);
进行红黑转换。