java集合学习之ArrayDeque,PriorityQueue

总结学习自《java核心技术卷Ⅰ》

一.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());
   }
}

猜你喜欢

转载自blog.csdn.net/c1776167012/article/details/106582452
今日推荐