总结学习自《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);
        }
    }
}

java ArrayMap 可以存null java arrayqueue_构造方法

二.此类的基本组成学习

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