Java 集合学习笔记【二】
Properties
因为这个和 IO 的流输入流输出有关,所以日后再来补坑。
Queue
首先来看看 Queue 接口:
1 | public interface Queue<E> extends Collection<E> |
这里可以看到是和 List 同级别的接口,都继承了 collection,顾名思义啊,这个 Queue 就是一个实现了队列功能的集合,First In First Out 先进先出。
而在 Java 中,实现 Queue 接口的类是:LinkedList,虽说它叫作 LinkedList ,但是它实际上是实现了 List 和 Queue 两个接口。我们可以向上转型为 Queue,然后把它当作队列的实例使用。
看一看 Queue 里面封装的方法:
1 | boolean add(E e); //向队列尾部加入元素 |
上面相同的功能有两种不同的方法实现,一个是常用词(add,remove,element),另一个是非常用词(offer,poll,peek),两者的区别就是前者出错时直接抛出异常,后者时返回 null。
PriorityQueue
优先队列,在 Java 中使用堆结构实现。为 PriorityQueue 类,并实现了 Queue 接口。其所拥有的的方法和 Queue 差不多,唯一的不同是队列开头的元素是按照自己要求排出来的第一。
因为涉及到了比较,所以和 TreeMap 以及 Collections.sort() 一样,要么在元素的类中实现 Comparable 接口中的 compareTo() 方法,要么在建立 PriorityQueue 实例的时候传入一个 Comparator 的匿名类进去。
Deque
Deuqe 是个双端队列,双端队列故名思意就是可以在队列头和队列尾都添加元素的队列,同样是实现了FIFO先进先出的特性。ArrayDeque 和 LinkedList 两者实现了 Deque 接口(好家伙 LinkedList 也太全能了吧),而 Deque 接口规定了必须要实现的方法:
功能 | Deque |
---|---|
添加元素到队尾 | addLast(E e) / offerLast(E e) |
取队首元素并删除 | E removeFirst() / E pollFirst() |
取队首元素但不删除 | E getFirst() / E peekFirst() |
添加元素到队首 | addFirst(E e) / offerFirst(E e) |
取队尾元素并删除 | E removeLast() / E pollLast() |
取队尾元素但不删除 | E getLast() / E peekLast() |
用法和优先队列的 Queue 完全相同,而且 Deque 也是继承于 Queue 接口的。
1 | public interface Deque<E> extends Queue<E> |
所以 Deque 也可以使用 offer() 添加元素到队尾,但是并不推荐这样写,对于这种双端队列,还是写成 offerLast() 这样更明确一些。
因为像 LinkedList 这样实现了很多不同接口的类,我们具体要把它当作某一个接口使用的时候,因该让它向上转型为对应的接口,然后按照接口拥有的功能进行操作,这种尽量持有接口的方法才是面向对象的思想。
Stack
众所周知,栈是一个先进后出的数据结构,和叠碗筷差不多。在 Java 中并没有单独搞一个叫作 Stack 的接口,这是因为历史遗留问题,有一个单独叫作 Stack 的类,因为这个 Stack 类所拓展的 Vector 类是一个早期 Java 写的一个不太行的类,里面很多方法都是线程安全的,速度很慢,所以就直接废弃不用了。
那如何实现栈结构呢?当然是使用万能的双端队列 Deque 啦,Deque 接口就封装了栈所需要的一些方法,如:
- 把元素压入栈中: push(E)/addFirst(E)
- 把元素弹出栈:pop(E)/removeFirst(E)
- 取栈顶元素但不弹出: peek(E)/peekFirst(E)
如果将 Deque 当作 Stack 使用的时候,尽量用 push pop peek 这样的方法,更直接清晰。
栈数据结构的用途非常多,以后会慢慢学的。