Java集合-Collection解析
前言
对于Java.util.Collection接口应该都不陌生,使用其实现的集合框架还是有很多需要深入了解的,接下来先看一下Java集合框架图。首先框架图中表明了4种关系
- List与Collection的实现关系
- ArrayList与AbstractList的继承关系
- Map与Collection的依赖关系
- Comparable 与Comparator的双向关联关系
对于上述集合框架的关系,主要有三种
- 集合基础规范接口:Collection、List、Set、 Queue Map
- 基于接口实现的抽象容器: AbstractCollection、 AbstractList 、AbstractSet、 AbstractMap、AbstractSequentialList
- 具体实现类:Vector、 Stack、 ArrayList、 LinkedList、 HashSet 、LinkedHashSet 、TreeSet、 HashMap 、LinkedHashMap、 HashTable 、WeakHashMap 、 TreeMap、 IdentityHashMap
上面是集合框架中的抽象和实现之间的关系,还有几个用于实现集合所拥有的算法和框架基本方法规则类Iterator、 ListIterator、 Collections 、Arrays 、Comparable 与Comparator
java util包主要为我们实现了动态数组,链表,树,哈希表这些数据结构,对于不同的数据结构的特性又进一步进行扩展,
集合类介绍
Collection接口与AbstractCollection抽象类
Collection接口是一个根接口,List Set Queue等都是实现了这个接口,AbstractCollection是一个抽象类,其实现了Collection接口,对比下Collection其具体对方法做了实现,以及在Collection基础上做了哪些扩展
Collection | AbstractCollection |
---|---|
int size() | public abstract int size() |
boolean isEmpty() | public boolean isEmpty(){…} |
boolean contains(Object o) | public boolean contains(Object o) {…} |
Iterator iterator() | public abstract Iterator iterator() |
Object[] toArray() | public Object[] toArray() {…} |
T[] toArray(T[] a) | public T[] toArray(T[] a) { {…} |
default T[] toArray(IntFunction<T[]> generator) {…} | — |
boolean add(E e) | public boolean add(E e){…} |
boolean remove(Object o) | public boolean remove(Object o){…} |
boolean containsAll(Collection<?> c) | public boolean containsAll(Collection<?> c) {…} |
boolean addAll(Collection<? extends E> c) | public boolean addAll(Collection<? extends E> c) {…} |
boolean removeAll(Collection<?> c) | public boolean removeAll(Collection<?> c) {…} |
default boolean removeIf(Predicate<? super E> filter){…} | — |
boolean retainAll(Collection<?> c) | public boolean retainAll(Collection<?> c) {…} |
void clear() | public void clear() {…} |
boolean equals(Object o) | — |
int hashCode() | — |
default Spliterator spliterator(){…} | — |
default Stream stream() {…} | — |
default Stream parallelStream() {…} | — |
— | private static T[] finishToArray(T[] r, Iterator<?> it) {…} |
— | private static int hugeCapacity(int minCapacity){…} |
— | public String toString() {…} |
- boolean contains(Object o):判断当前集合中是否含有某个元素
- Iterator iterator():循环迭代元素
- boolean containsAll(Collection<?> c):判断元素是否相等
- default boolean removeIf(Predicate<? super E> filter){…}:根据判断删除元素
- boolean retainAll(Collection<?> c):删除集合A不在集合B中的元素
- default Spliterator spliterator(){…}:创造一个分离器,与并发处理有关
- default Stream stream() {…}:也是与并发处理有关—创建一个集合的操作流(单线程流)
- default Stream parallelStream() {…}:创建一个集合的并行操作流
retainAll()
int[] list1={1,2,3,4,6,5};
int [] list2={1,2,3,4,53};
list1.retainAll(list2);
//list1中6,5不在list2中执行该方法时进行了移除操作返回true,如果将arr1改为{1,2,3,4},执行该方法无需进行移除操作返回false;
removeIf()
ArrayList<String> arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.removeIf(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.equals("1");
}
});
System.out.print("arrayList.size():" + arrayList.size()+"\n");
//打印:arrayList.size():1
long count = arrayList.stream().sorted().count();
long count = arrayList.parallelStream().sorted().count();
//parallelStream()的排序时间上快于stream()
List、Set、Queue、Collection接口方法对比
方法 | List | Set | Queue | Collection |
---|---|---|---|---|
int size() | * | * | — | * |
boolean isEmpty() | * | * | — | * |
boolean contains(Object o) | * | * | — | * |
Iterator iterator() | * | * | — | * |
Object[] toArray() | * | * | — | * |
T[] toArray(T[] a) | * | * | — | * |
default T[] toArray(IntFunction<T[]> generator) | — | — | — | * |
boolean add(E e) | * | * | * | * |
boolean remove(Object o) | * | * | — | * |
boolean containsAll(Collection<?> c) | * | * | — | * |
boolean addAll(Collection<? extends E> c) | * | * | — | * |
boolean addAll(int index, Collection<? extends E> c) | * | — | — | — |
boolean removeAll(Collection<?> c) | * | * | — | * |
boolean retainAll(Collection<?> c) | * | * | — | * |
default void replaceAll(UnaryOperator operator){…} | * | * | — | — |
default void sort(Comparator<? super E> c){…} | * | — | — | — |
void clear() | * | * | — | * |
boolean equals(Object o) | * | * | — | * |
int hashCode() | * | * | — | * |
E get(int index) | * | — | — | — |
E set(int index, E element) | * | — | — | — |
void add(int index, E element) | * | — | — | — |
E remove(int index) | * | — | — | — |
int indexOf(Object o) | * | — | — | — |
int lastIndexOf(Object o) | * | — | — | — |
ListIterator listIterator() | * | — | — | — |
ListIterator listIterator(int index) | * | — | — | — |
List subList(int fromIndex, int toIndex) | * | — | — | — |
default Spliterator spliterator(){…} | * | * | — | — |
static List of(){…} | * | *(返回参数Set) | — | — |
static List of(…){…} | * | *(返回参数Set) | — | — |
static List copyOf(Collection<? extends E> coll){…} | * | *(返回参数Set) | — | — |
boolean offer(E e) | — | — | * | — |
E remove() | — | — | * | — |
E poll() | — | — | * | — |
E element() | — | — | * | — |
E peek() | — | — | * | — |
default boolean removeIf(Predicate<? super E> filter){…} | — | — | — | * |
default Spliterator spliterator(){…} | — | — | — | * |
default Stream stream() {…} | — | — | — | * |
default Stream parallelStream() {…} | — | — | — | * |
AbstractList、AbstractSequentialList、AbstractSet方法对比
AbstractList
继承AbstractCollection
,AbstractSequentialList继承AbstractList
,AbstractSet继承AbstractCollection
;这里我们可以看看AbstractSequentialList相对AbstractList又做了哪些扩展,又有哪些方法是没有实现,扩展的方法就是为了实现LinkedList
方法 | AbstractList | AbstractSequentialList | AbstractSet |
---|---|---|---|
public boolean add(E e){…} | * | — | — |
public abstract int size() | * | — | — |
public boolean isEmpty(){…} | * | — | — |
public boolean contains(Object o){…} | * | — | — |
public abstract E get(int index) | * | * | — |
public E set(int index, E element){…} | * | * | — |
public void add(int index, E element){…} | * | * | — |
public E remove(int index){…} | * | * | — |
public int indexOf(Object o){…} | * | — | — |
public int lastIndexOf(Object o){…} | * | — | — |
public void clear(){…} | * | — | — |
public boolean addAll(int index, Collection<? extends E> c){…} | * | * | — |
public abstract Iterator iterator() | * | * | * |
public ListIterator listIterator(){…} | * | — | — |
public ListIterator listIterator(final int index){…} | * | * | — |
public List subList(int fromIndex, int toIndex){…} | * | * | — |
static void subListRangeCheck(int fromIndex, int toIndex, int size){…} | * | — | — |
public boolean equals(Object o){…} | * | — | — |
public int hashCode(){…} | * | — | * |
protected void removeRange(int fromIndex, int toIndex){…} | * | — | — |
private void rangeCheckForAdd(int index){…} | * | — | — |
private String outOfBoundsMsg(int index){…} | * | — | — |
public boolean equals(Object o){…} | — | — | * |
public boolean removeAll(Collection<?> c){…} | — | — | * |
实现类介绍
Vector、 Stack、 ArrayList、 LinkedList、 HashSet 、LinkedHashSet 、TreeSet、 HashMap 、LinkedHashMap、 HashTable 、WeakHashMap 、 TreeMap、 IdentityHashMap
容器类 | 父类及实现 | 描述 |
---|---|---|
ArrayList | extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable | 使用数组实现,在数据逻辑上是连续的,物理逻辑也是连续的,插入和删除需要挪动元素位置所以比较慢,查询较快, |
LinkedList | extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable | 双向链表的方式实现,每一个节点保存前后节点的引用以及本身的值,在数据逻辑上是连续的,物理逻辑是不连续的,插入删除比较快,查询稍慢 |
Vector | extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable | Vector是一个矢量队列,继承与实现和ArrayList相同,同样是数组实现。区别是Vector的方法都使用synchronized修饰,所以这是一个线程安全的容器。Vector在Java中出现的比较早,在后面使用提高并发性能的CopyOnWriteArrayList进行优化替代,CopyOnWriteArrayList实现读写分离,只有在写的时候是加锁的,存在数据一致性问题 |
Stack | extends Vector | 使用数组实现的栈,具有Vector线程安全特点。主要特点是先进后出,我们也可以使用LinkedList实现 |
HashMap | extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable | 使用Hash表实现的Map,Hash表具有极高的查询效率,理想情况下取值时间复杂度为O(1),但存在Hash碰撞,HashMap解决hash碰撞的方式是链地址法,理解HashMap主要学习HashMap中的hash()方法,以及配合hash()方法所需要的初始容量大小,扩容倍数 |
HashTable | extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable | 上图的HashTable继承方法有错误。Hashtable是一个散列表,方法是同步的,而HashMap的不是。Hashtable它的key、value都不可以为null。HashMap允许一个键为null,多个value为null。在线程优化上Java 5提供ConcurrentHashMap |
TreeMap | extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable | TreeMap实现NavigableMap接口,NavigableMap继承SortedMap,所以TreeMap具有排序的功能,默认情况下按照key的字典顺序来排序。在性能上TreeMap是红黑树实现,但是与HashMap的Hash表相比还是慢一些,所以如果需要对添加的元素进行排序可以选择TreeMap |
LinkedHashMap | extends HashMap<K,V> implements Map<K,V> | 首先HashMap是以 Key 做 Hash 算法,然后将hash值映射到内存地址,然后将内存地址转换后作为数组的下标索引,但取值得时候不能保证按照存的时候顺序进行取值。LinkedHashMap在HashMap的基础上,又在内部增加了一个链表,用以存放元素的顺序。在取出元素顺序上,LinkedHashMap保证的是元素存储的顺序,TreeMap保证的是key的字典顺序,或者是设置排序方式 |
WeakHashMap | extends AbstractMap<K,V> implements Map<K,V> | WeakHashMap的特点是,当除了自身有对key的引用外,此key没有其他引用那么此map会自动丢弃此值,同时将a、b两个对象存入HashMap和WeakHashMap,当删除掉a,并将a、b都指向null时,WeakHashMap中的a将自动被回收掉,这就是WeakReference和ReferenceQueue实现的WeakHashMap的弱键 |
IdentityHashMap | extends AbstractMap<K,V> implements Map<K,V>, java.io.Serializable, Cloneable | IdentityHashMap与HashMap最大的不同是在比较key是否相等,(p.hash == hash &&((k = p.key) == key 或 (key != null && key.equals(k)))) , IdentityHashMap是(item == k) 。IdentityHashMap比较键(和值)时使用引用相等性代替对象相等性。 |
HashSet | extends AbstractSet implements Set, Cloneable, java.io.Serializable | HashSet的特点是不许重复,比较的效率就很关键,使用Hash表实现的HanshMap能解决这个问题。在存储对象的时候需要实现hashCode()和equals()方法,数据的存取是无序的,集合元素可以是null,但只能放入一个null |
LinkedHashSet | extends HashSet implements Set, Cloneable, java.io.Serializable | 使用LinkedHashMap存储数据,具有LinkedHashMap的特性,同时具有Set的特性 |
TreeSet | extends AbstractSet implements NavigableSet, Cloneable, java.io.Serializable | TreeSet 是一个有序的集合,它的作用是提供有序的Set集合,其实现方式使用TreeMap,具有TreeMap的特性 |
Iterator、 ListIterator、 Collections 、Arrays 、Comparable 与Comparator
terator
ArrayList中有一个内部类Itr
其实现Iterator接口,Iterator提供一套接口用于标准化迭代数据,主要含有boolean hasNext()
- ListIterator
Collections
Collections不属于集合框架,Collection是一个工具类,包含各种集合的搜索、排序、线程安全等操作,主要服务于 Collection集合框架,Collections不能被实例化,提供方法为静态方法。Arrays
Arrays也不属于集合框架,和Collections一样是一个工具类,其主要作用是为数组提供排序,比较、替换等工作。Arrays不能实例化,提供的为静态方法。java.lang.Comparable
Comparable是排序接口且,只有一个方法public int compareTo(T o);实现Comparable的类默认可以使用 Collections.sort(或 Arrays.sort)进行排序,比如String类和Integer类就实现了Comparable接口java.util.Comparator
Comparator是比较器,若需要控制某个类A的次序,可以建立一个“该类的比较器”来进行排序。只需要某一个工具类实现Comparator接口,在泛型中传递A对象,工具类实现Comparator 中的compare()方法,在compare()编写比较算法,那么调用Collections.sort(list, new Utis())就可以进行比较了;相对于Comparable接口,Comparator更加的解耦,只需要在外部实现,所以我们称为“外部比较器“,Comparable为”内部比较器“
Java 集合框架
Collection架构源码分析(基于1.8)
java源码阅读之Spliterator
Java8新特性
Java 中 Comparable 和 Comparator 比较