总结学习自《java核心技术卷Ⅰ》
文章目录
- 一.ArrayDeque基础学习
- 1.何为ArrayDeque?
- 2.构造方法
- 3.其他的一些方法
- 4.使用实例
- 二.此类的基本组成学习
- 1.继承和实现
- 2.探索add方法和get方法
- 1)构造方法
- 2.add类方法
- 3.get类方法
- 三.PriorityQueue学习
- 1.什么是PriorityQueue?
- 2.它为何能这样?
- 使用例子
一.ArrayDeque基础学习
1.何为ArrayDeque?
它是java类库java.util中的一个类,他的主要功能就是提供一个双端队列供我们使用。队列又称先进先出表,双端队列,顾名思义,就是任何一端根据我们的需要既可以当队头也可以当作队尾。
2.构造方法
方法名 | 描述 |
ArrayDeque() | 构造一个空数组deque,初始容量足以容纳16个元素。 |
ArrayDeque(Collection<? extends E> c) | 构造一个包含指定集合元素的deque,按照它们由集合的迭代器返回的顺序。 |
ArrayDeque(int numElements) | 构造一个空数组deque,初始容量足以容纳指定数量的元素。 |
3.其他的一些方法
方法名 | 描述 |
boolean add(E e) | 在此deque的末尾插入指定的元素。 |
void addFirst(E e) | 在此deque前面插入指定的元素。 |
void addLast(E e) | 在此deque的末尾插入指定的元素。 |
void clear() | 从这个deque中删除所有的元素。 |
ArrayDeque clone() | 返回此deque的副本。 |
boolean contains(Object o) | 如果此deque包含指定的元素,则返回 true 。 |
Iterator descendingIterator() | 以相反的顺序返回此deque中的元素的迭代器。 |
E getFirst() | 检索,但不删除,这个deque的第一个元素。 |
E getLast() | 检索,但不删除,这个deque的最后一个元素。 |
boolean isEmpty() | 如果此deque不包含元素,则返回 true 。 |
Iterator iterator() | 返回此deque中的元素的迭代器。 |
E peekFirst() | 检索但不删除此deque的第一个元素,如果此deque为空,则返回 null 。 |
E peekLast() | 检索但不删除此deque的最后一个元素,或返回 null如果此deque为空)。 |
E pollFirst() | 检索并删除此deque的第一个元素,如果此deque为空,则返回 null 。 |
E pollLast() | 检索并删除此deque的最后一个元素,如果此deque为空,则返回 null 。 |
boolean remove(Object o) | 从此deque中删除指定元素的单个实例。 |
boolean removeFirstOccurrence(Object o) | 删除此deque中指定元素的第一个出现(从头到尾遍历deque时)。 |
boolean removeLastOccurrence(Object o) | 删除此deque中指定元素的最后一次(从头到尾遍历deque时)。 |
int size() | 返回此deque中的元素数。 |
Object[] toArray() | 以适当的顺序返回一个包含此deq ue中所有元素的数组(从第一个到最后一个元素)。 |
4.使用实例
public class example9_4 {
public static void main(String[] args) {
ArrayDeque<Integer> test=new ArrayDeque();
test.addFirst(4);
test.add(3);
test.addFirst(2);
test.add(1);
for (Integer e :test)
{
System.out.println(e);
}
}
}
二.此类的基本组成学习
1.继承和实现
首先我们通过前面的学习可以猜测它可能主要实现了Queue接口,继承了AbstractQueue骨架类。
于是我们查看源码发现:
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable
我们猜错了,我们为什么会猜错呢?
1)于是查询了Deque接口
public interface Deque<E> extends Queue<E>
发现Deque接口继承了Queue接口,也就是说我们没猜错,ArrayDueue确实间接实现了Queue接口。
2)那么它为什么不是继承AbstractQueue骨架类而是继承了AbstractCollection骨架类。
我们查看AbstractQueue的API发现:这个类提供了一些Queue操作的骨架实现。这个骨架类主要实现的是单端队列的接口,而ArrayDeque是双端队列,我们必须从头开始进行实现类的编写,而继承AbstractCollection可以减少编写的工作量。
2.探索add方法和get方法
下面以上面的实例为例子来进行解析:
1)构造方法
ArrayDeque<Integer> test=new ArrayDeque();
走进这个构造方法中:
public ArrayDeque() {
elements = new Object[16];
}
可以发现它使用了一个默认大小为16的数组来存储元素。
2.add类方法
test.addFirst(4);
查看源码:
public void addFirst(E e) {
if (e == null)
throw new NullPointerException();
elements[head = (head - 1) & (elements.length - 1)] = e;
if (head == tail)
doubleCapacity();
}
其中head开始默认为0,在这里我们插入第一个元素,也就是有:
head=(0-1)&(16-1)=15。
即在这个双端队列中,elements[15]=4;
然后执行:
test.add(3);
源码:
public boolean add(E e) {
addLast(e);
return true;
}
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
}
*从源码我们可以看出其实执行add就是执行addLast:
其中tail默认为0:tail=(0+1)&(16-1)=1
我们可以得到:elements[0]=3;tail=1
接着的:
test.addFirst(2);
test.add(1);
我们可以得出:elements[14]=2; elements[1]=1;
此时head=14;tail=2;
3.get类方法
故当我们调用getFirst时:
public E getFirst() {
@SuppressWarnings("unchecked")
E result = (E) elements[head];
if (result == null)
throw new NoSuchElementException();
return result;
}
返回的是elements[14];
调用getLast:
public E getLast() {
@SuppressWarnings("unchecked")
E result = (E) elements[(tail - 1) & (elements.length - 1)];
if (result == null)
throw new NoSuchElementException();
return result;
}
返回的是elements[1];
上述只是简单的探索了一些方法,我们也可以根据API和源码来探索其他方法。
三.PriorityQueue学习
1.什么是PriorityQueue?
顾名思义,它是一个优先级队列类。优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索,换句话说,我们无论何时调用remove方法,总会获得当前优先级队列中的最小元素。
2.它为何能这样?
其中的关键在于PriorityQueue中使用了一个数据结构:堆。
相关方法可以查看API这里不详细学习。
使用例子
package priorityQueue;
import java.util.*;
import java.time.*;
public class PriorityQueueTest
{
public static void main(String[] args)
{
PriorityQueue<LocalDate> pq = new PriorityQueue<>();
pq.add(LocalDate.of(1906, 12, 9)); // G. Hopper
pq.add(LocalDate.of(1815, 12, 10)); // A. Lovelace
pq.add(LocalDate.of(1903, 12, 3)); // J. von Neumann
pq.add(LocalDate.of(1910, 6, 22)); // K. Zuse
System.out.println("Iterating over elements...");
for (LocalDate date : pq)
System.out.println(date);
System.out.println("Removing elements...");
while (!pq.isEmpty())
System.out.println(pq.remove());
}
}