java之Collection
java中的Collection可分为List、Set、Queue三种类型。
1、List。
List会按照插入的顺序保存对象,较为常用的实现类有ArrayList,LinkedList和Vector。
(1)ArrayList是通过数组实现的。当容量不足时,会扩容增加原容量的1/2。数组的缺陷是显而易见的,进行删除和扩容时的复制操作非常耗费资源;但它的优点是遍历和访问速度快。
ArrayList扩容源码:
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
(2)LinkedList是通过链表实现的。添加元素时,直接将新元素加到链表的末端。它适用于增加和删除元素,但不适用于访问和遍历。
LinkedList添加元素源码:
void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
(3)Vector与ArrayList类似,都是通过数组实现的,最大的区别是,Vector线程安全,而ArrayList非线程安全;还有就是Vector的扩容增量可自己设置,若不设置,则扩容时将增加一倍。
Vector扩容源码:
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
2、Set。
Set不保存重复的元素,它通常用于查询是否存在某个元素。它的常用实现类有HashSet、TreeSet。
(1)HashSet的底层通过HashMap实现,也可以选择LinkedHashMap。将插入的值作为Key插入到HashMap中,把Object对象常量作为Value。
添加元素操作源码:
public boolean add(E e) { return map.put(e, PRESENT)==null; }
(2)TreeSet通过TreeMap实现,与HashSet一样,也是将插入的元素作为Key,把Object对象常量最为Value。
设置排序方式源码:
public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); }
3、Queue。
队列通常是一种FIFO的容器,但也可根据具体需求设置优先级。
表1中展示了队列的几个基本操作:
(1)add和offer方法都是往队列中添加元素,在一些容量限制的队列中,插入失败时,add方法将抛出异常;offer方法返回false。
(2)remove和poll方法都会移除并返回首个元素,当队列为空时,分别会抛出异常和返回null。
(3)element和peek方法都会返回首个元素而且不会移除,当队列为空时,分别会抛出异常和返回null。
表1 Queue的三对基本操作
抛出异常 | 返回特殊值 | |
插入 | add(e) |
offer(e) |
移除 | remove() |
poll() |
检查 | element() |
peek() |
Queue较为常用的实现类有LinkedList、PriorityQueue。
(1)LinkedList在上文中提到过,它是通过列表的形式实现的。它实现了List接口,同时也实现了Queue接口。
通常我们会根据需要将其向上转型为List或Queue类型,这里体现了向上转型的一个优点,它窄化了子类成员的访问权限,方便使用。
(2)PriorityQueue是无界优先级队列,它有以下特点:
它可根据自然顺序或根据提供的Comparator进行排序。
不允许插入不可比较的对象,若插入的元素类型未实现Comparable接口,且不提供Comparator对象,将会出错。
不允许插入null元素。