版本:java11,集合容器里都是极其经典的设计思想,虽然平常用的只是其中个别,但在更高级的开发会用到其他集合,在开发中处处收益。
支持迭代的集合的爸爸,定义了集合最基本的操作
//获得大小
int size();
//是否为空
boolean isEmpty();
//是否包括元素
boolean contains(Object var1);
//迭代器
Iterator<E> iterator();
//变成数组
Object[] toArray();
//新增一个
boolean add(E var1);
//删除指定
boolean remove(Object var1);
//清空
void clear();
//获取流
default Stream<E> stream() {
return StreamSupport.stream(this.spliterator(), false);
}
列表的接口,定义增删查改方法,直接继承Collection
除了继承来的方法,还有以下常用
//输出首次出现下标
int indexOf(Object var1);
//输出最后出现下标
int lastIndexOf(Object var1);
//初始化时,填入一列值
@SafeVarargs
static <E> List<E> of(E... elements) {
switch(elements.length) {
case 0:
return ImmutableCollections.emptyList();
case 1:
return new List12(elements[0]);
case 2:
return new List12(elements[0], elements[1]);
default:
return new ListN(elements);
}
}
//复制一个列表
static <E> List<E> copyOf(Collection<? extends E> coll) {
return ImmutableCollections.listCopy(coll);
}
抽象类,是list和set的实现类共同的爸爸
声明队列
声明双向链表
链表,链表相关的方法是实现Deque中的
主要成员变量如下
transient int size;
transient LinkedList.Node<E> first;
transient LinkedList.Node<E> last;
下面这几个是同样的功能,在开头加入一个
public void push(E e);
public void addFirst(E e);
private void linkFirst(E e) ;
也能在末尾加一个
public void addLast(E e);
public boolean add(E e);
/*末尾弹出一个*/
public E removeLast();
public E pop();
//弹出第一个
public E removeFirst();
继承AbstractCollection实现List,有了集合的性质,又有了列表的特点的抽象类
实现了链表的部分功能
顺序表,内部维护了一个数组,内部操作主要靠Arrays类
transient Object[] elementData;
添加时的操作
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length) {
elementData = this.grow();
}
elementData[s] = e;
this.size = s + 1;
}
public boolean add(E e) {
++this.modCount;
this.add(e, this.elementData, this.size);
return true;
}
自动扩容,这块和java8明显不一样,java8是扩容1.5倍,到这一代是随时扩容,我也不太清楚从哪个版本开始的
//ArrayList中的扩容代码,每一次add都会执行
private Object[] grow(int minCapacity) {
return this.elementData = Arrays.copyOf(this.elementData, this.newCapacity(minCapacity));
}
private Object[] grow() {
return this.grow(this.size + 1);
}
//将已有的数组复制到新的数组里,在Arrays类中
@HotSpotIntrinsicCandidate
public static <T, U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = newType == Object[].class ? new Object[newLength] :(Object[])Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
无序唯一集合的接口,定义增删查改方法
set实现类都是对map实现类的封装
对set接口的部分实现
无序唯一映射关系的接口,定义增删查改方法
//元素个数
int size();
//是否为空
boolean isEmpty();
//是否包括key
boolean containsKey(Object var1);
//是否包括值
boolean containsValue(Object var1);
//获取一个
V get(Object var1);
//加入一个
V put(K var1, V var2);
//删除一个
V remove(Object var1);
//把另一个map中所有的元素合并过来
void putAll(Map<? extends K, ? extends V> var1);
//获得key的set集合
Set<K> keySet();
//获得entry的set集合
Set<Map.Entry<K, V>> entrySet();
对map接口的部分实现
有序的set和map
//第一个
K firstKey();
//最后一个
K lastKey();
//返回在两个key之间的集合,包括两个key
SortedMap<K, V> subMap(K var1, K var2);
//返回小于定于key的集合
SortedMap<K, V> headMap(K var1);
//返回小于定于key的集合
SortedMap<K, V> tailMap(K var1);
/*同上,bool值表示是否等于*/
NavigableMap<K, V> subMap(K var1, boolean var2, K var3, boolean var4);
NavigableMap<K, V> headMap(K var1, boolean var2);
NavigableMap<K, V> tailMap(K var1, boolean var2);
JDL1.6增加的俩接口,定义一些范围筛选的方法,下面是navigableMap定义的方法
//返回小于等于给定键的最大键
K floorKey(K var1);
//返回大于等于给定键的最小键
K ceilingKey(K var1);
//返回小于给定键的最大键
K lowerKey(K var1);
//返回大于给定键的最小键
K higherKey(K var1);
/*下面四个对应上面四个,返回键值映射关系*/
Entry<K, V> lowerEntry(K var1);
Entry<K, V> floorEntry(K var1);
Entry<K, V> ceilingEntry(K var1);
Entry<K, V> higherEntry(K var1);
HashSet是值都为空的HashMap,key可以有几个null
部分源码这么写的,下面两个set同理,set看上去只有个不重复的key,忽略value
//内部定义一个HashMap
private transient HashMap<E, Object> map;
//添加的时候
public boolean add(E e) {
return this.map.put(e, PRESENT) == null;
}
//其中PRESENT是一个新建的对象
private static final Object PRESENT = new Object();
LinkedHashSet是值都为空的LinkedHashMap
TreeSet是值都为空的TreeMap,key值存在一颗红黑树上,保证了key的有序
弱引用连接的hashMap,Entry继承WeakReference
public class WeakReference<T> extends Reference<T> {
public WeakReference(T referent) {
super(referent);
}
public WeakReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}
}