JAVA基础知识之Queue集合
- Queue接口
- PriorityQueue类
- Deque与ArrayDeque
- LinkedList
- 各种线性表性能分析
Queue接口
Queue用来模拟队列这种数据结构,遵循先进先出原则(FIFO)。Queue接口中定义了以下通用方法,remove(), element():获取队头元素,remove(), poll(), peek():获取队头元素;offer(Object obj):队尾插入,容量限制时比add()好; add(Object obj);
PriorityQueue
PriorityQueue中的元素会按照自然排序(由元素实现Comparable接口决定排序逻辑)或者定制排序(由集合的实现Comparable接口决定排序逻辑),而不是按照插入顺序排序(从这点来说已经违反队列定义)。元素的顺序在队列构造的时候,由构具体使用的哪个构造函数来决定。PriorityQueue不允许插入null元素。PriorityQueue内部是用数组保存数据的,源码如下,
- //JDk源码
- private transient Object queue[];
下面说说两种排序方式,
自然排序(元素实现Comparable决定排序逻辑)
元素必须实现了Comparator接口,而且所有元素都是同类型的,否则会抛出异常。下面是一个自然排序的例子,
- package collect.Queue;
- import java.util.Comparator;
- import java.util.Iterator;
- import java.util.PriorityQueue;
- class A implements Comparable{
- private int age;
- public A(int age) {
- this.age = age;
- }
- @Override
- public int compareTo(Object o) {
- if (this == o) return 0;
- A a = (A)o;
- return this.age - a.age;
- }
- public String toString() {
- return String.valueOf(this.age);
- }
- }
- public class PriorityQueues {
- public static void main(String[] args) {
- PriorityQueue pq = new PriorityQueue();
- pq.add(new A(100));
- pq.add(new A(50));
- pq.add(new A(300));
- pq.add(new A(150));
- pq.add(new A(-200));
- //System.out.println(pq);
- Iterator it = pq.iterator();
- while(it.hasNext()) {
- System.out.println(pq.poll());
- }
- }
- }
注意上面System.out.println(pq)的输出结果元素并不是按大小排序的, 整个执行结果如下,
- [-200, 50, 300, 150, 100]
- ============================
- -200
- 50
- 100
- 150
- 300
据李刚的《疯狂JAVA讲义》的解释说,是因为toString()的返回值的影响,说如果用poll()就能看到大小顺序(确实看到了)。但是网上有博客又说,是因为PriorityQueue底层数据结构的原因,底层是用一个“最小堆”来保持元素顺序的。 至于真正原因是什么,我也还需要进一步研究。
Deque是Queue的子接口,Queue是一个单端队列,而Deque接口是一个双端队列,因此定义了一些允许从两端操作队列的方法,
addFirst, addLast, descendingIterator,getFirst, getLast, offerFirst, offerLast, peekFirst, peekLast, pollFirst, pollLast, pop, poll, push(相当于addFirst),removeFirst, removeLast, removeOccurrenc(Object o)...
注意Deque接口里面同时定义了pop, poll , push等栈容器的方法,所以Deque也可以当作栈来使用,
ArrayDeque是Deque的一个典型的实现类,ArrayDeque是基于动态数组的集合,与ArrayList非常相似,不同点是ArrayList具有链表功能,支持随机访问(get),而ArrayDeque具有队列和栈功能,下面的例子演示了ArrayDeque的两种典型用法,
- package collection.queues;
- import java.util.ArrayDeque;
- public class ArrayDeques {
- public static void main(String[] args) {
- ArrayDeque ad = new ArrayDeque();
- /*use ArrayDeque as a Queue*/
- ad.offer("a");
- ad.offer("b");
- ad.offer("c");
- ad.offer("d");
- System.out.println(ad);
- //the peek and poll method from Queue interface
- System.out.println(ad.peek());
- System.out.println(ad.poll());
- System.out.println(ad);
- /*use ArrayDeque as a Deque*/
- //use push and pop method from Deque interface
- ad.push("e");
- ad.push("f");
- System.out.println(ad);
- System.out.println(ad.peek());
- System.out.println(ad.pop());
- System.out.println(ad);
- }
- }
输出结果,
- [a, b, c, d]
- a
- a
- [b, c, d]
- [f, e, b, c, d]
- f
- f
- [e, b, c, d]
LinkedList
LinkedList同时实现了Deque, Queue, List三个接口,所有具有强大的功能。既能支持随机访问(get),又能支持队列和栈的属性,下面是LinkedList集合了个种属性的用法,
- package collection.queues;
- import java.util.LinkedList;
- public class LinkedLists {
- public static void main(String[] args) {
- LinkedList ll = new LinkedList();
- //use as a Queue
- ll.offer("a");
- //use as a Stack(Deque), insert an element from head
- ll.push("b");
- //use as a Deque, insert an element from tail
- ll.offerLast("c");
- //use as a List, insert an element in index of 2
- ll.add(2, "d");
- //travel as a List
- for (int i=0; i<ll.size(); i++) {
- System.out.print(ll.get(i));
- }
- System.out.println("\n--------------------");
- //use as a Deque
- System.out.println(ll.peekLast());
- System.out.println(ll.pollLast());
- System.out.println(ll.pollFirst());
- System.out.println("--------------------");
- System.out.println(ll);
- }
- }
执行结果,
- badc
- --------------------
- c
- c
- b
- --------------------
- [a, d]
各种线性表性能分析
Java的List是一个线性表接口,ArrayList和LinkedList是List的两种典型实现,都提供随机访问功能(get)。只是ArrayList基于数组,随机访问更快;LinkedList基于链表,插入删除更快,且同时还实现了Queue和Deque两个接口,因此同时具有链表,双端队列,栈的三种功能。
Queue是一种队列,而Deque是双端队列,同时具有队列和栈的功能。
虽然ArrayList和LinkedList都支持随机访问,但由于底层数据结构不同,ArrayList的空间分布在连续的内存上,因此随机访问的性能比LinkedList好。所有以数组作为底层数据结构的集合的随机访问性能都更好。而LinkedList因为底层是链表结构,因此插入和删除的性能更好。但是总体上来说,ArrayList的性能要比LinkedList性能好,因此大部分情况下都推荐用ArrayList.
对于List的使用,有如下建议,
- 遍历ArrayList和Vector时,尽量用随机访问方法(get),这样性能更好。 对于LinkedList,应该用迭代器(iterator)来遍历。
- LinkedList的应用场景:需要经常插入,删除包含大量数据的List集合。ArrayList和Vector需要经常重新分配空间,会影响性能。
JAVA基础知识之Queue集合的更多相关文章
- Java基础知识强化之集合框架笔记76:ConcurrentHashMap之 ConcurrentHashMap简介
1. ConcurrentHashMap简介: ConcurrentHashMap是一个线程安全的Hash Table,它的主要功能是提供了一组和Hashtable功能相同但是线程安全的方法.Conc ...
- Java基础知识强化之集合框架笔记39:Set集合之HashSet存储字符串并遍历
1. HashSet类的概述: (1)不保证set的迭代顺序 (2)特别是它不保证该顺序恒久不变 HashSet底层数据结构是哈希表,哈希表依赖于哈希值存储,通过哈希值来确定元素的位置, 而保证元素 ...
- Java基础知识强化之集合框架笔记27:ArrayList集合练习之去除ArrayList集合中的重复字符串元素
1. 去除ArrayList集合中的重复字符串元素(字符串内容相同) 分析: (1)创建集合对象 (2)添加多个字符串元素(包含重复的) (3)创建新的集合 (4)遍历旧集合,获取得到每一个元素 (5 ...
- Java基础知识强化之集合框架笔记07:Collection集合的遍历之迭代器遍历
1. Collection的迭代器: Iterator iterator():迭代器,集合的专用遍历方式 2. 代码示例: package cn.itcast_03; import java.util ...
- Java基础知识强化之集合框架笔记05:Collection集合的遍历
1.Collection集合的遍历 Collection集合直接是不能遍历的,所以我们要间接方式才能遍历,我们知道数组Array方便实现变量,我们可以这样: 使用Object[] toArray() ...
- Java基础知识强化之集合框架笔记65:Map集合之集合多层嵌套的数据分析
1. 为了更符合要求: 这次的数据就看成是学生对象. 传智播客 bj 北京校区 jc 基础班 林青霞 27 风清扬 30 jy 就业班 赵雅芝 28 武鑫 29 sh 上海 ...
- Java基础知识强化之集合框架笔记62:Map集合之HashMap嵌套HashMap
1. HashMap嵌套HashMap 传智播客 jc 基础班 陈玉楼 20 高跃 ...
- Java基础知识强化之集合框架笔记04:Collection集合的基本功能测试
1. Collection集合的基本功能测试: package cn.itcast_01; import java.util.ArrayList; import java.util.Collectio ...
- Java基础知识强化之集合框架笔记01:集合的由来与数组的区别
1. 集合的由来: 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.而要想存储多个对象,就不能是一个基本的变量,而应该 ...
随机推荐
- 为benchmarksql的PostgreSQL java驱动进行升级
为benchmarksql的PostgreSQL java驱动进行升级[root@minion1 benchmarksql-4.1.0]# wget https://jdbc.postgresql.o ...
- SQL查询一个表的总记录数的方法
一.简单查询语句 1. 查看表结构 SQL>DESC emp; 2. 查询所有列 SQL>SELECT * FROM emp; 3. 查询指定列 SQL>SELECT empmo, ...
- Lucas
C(n,m)%p=C(n%p,m%p)*C(n/p,m/p)%p 迭代递归 n,m非负整数,p质数 证明 最后一个由二项式定理和p进制数性质得出的我并没有看懂...
- map容器
map容器一般用于对字符串进行编号,主要用于建图方面,例如把城市名按数字进行编号 #include"stdio.h" #include"string.h" #i ...
- How to wipe silicon to CPU 如何给CPU正确涂抹硅脂
随 着计算机性能的提升,CPU的功耗也在不断的增大,虽然现在由于改进了工艺使得在功耗方面得到了一定的缓解,但由于近年来显卡性能的不断增强,也开始走上 了CPU功耗性能成正比的老路,功耗依然还是一个值得 ...
- hdu 2846 Repository
http://acm.hdu.edu.cn/showproblem.php?pid=2846 Repository Time Limit: 2000/1000 MS (Java/Others) ...
- [转]Hibernate不能自动建表解决办法及Hibernate不同数据库的连接及SQL方言
最近开始学Hibernate,看的是李刚的那本<轻量级java ee企业应用实战>.头一个hibernate程序,我原原本本的按照书上例子写下来,同时只是改动了些mysql的连接参数,并且 ...
- Python学习笔记总结1:字符串表示str与repr的用法比较
参考博文地址:http://blog.csdn.net/yyt8yyt8/article/details/7030416 值转化为字符串常用以下三种方法: 1. str函数 str函数转化为合理形式的 ...
- ActionController::InvalidAuthenticityToken 解决办法(第二种尤其有效)
第一种: Ror代码 class FooController < ApplicationController protect_from_forgery :except => ...
- php 无限循环
什么是无限分类呢?就像windows下新建一个文件夹,在新建的文件夹下又可以新建 一个文件夹,这样无限循环下去,无限分类也是这样,父类可以分 出它子类,子类又 可以分出它的子类,这样一直无限循环下去. ...