`
masterzs
  • 浏览: 16923 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JDK学习之Queue

阅读更多

今天学习Queue,基本数据类型,特点先进先出(FIFO)。

1.JDK中接口的定义:

         在jdk里边,LinkedList直接实现的Queue接口,所以我们可以使用LinkedList来模拟Queue,看一下几个

    主要方法:

2,主要方法解析:

    加入一条记录,offer(E o)

    public boolean offer(E o) {
        return add(o);
    }

         可以看到内部默认调用LinkedList的add方法,也就是默认放到队尾,head的previous指向,

    取出一条记录,

    public E poll() {
        if (size==0)
            return null;
        return removeFirst();
    }

    调用LinkedList的removeFirst方法,再看这个方法的实现:

 public E removeFirst() {
	return remove(header.next);
    }

 

    结果就是删除head.next指向的数据项,就是队列的第一个条数据,也是最早进入队列的数据。

 

   下边我们看下JDK中的继承关系,其中有个PriorityQueue,优先队列,怎么个优先法呢,我们看看其增加和删除方法

 

 

看下其成员变量和构造函数:

    private static final int DEFAULT_INITIAL_CAPACITY = 11;
    private transient Object[] queue;
    private int size = 0;
    private final Comparator<? super E> comparator;
    private transient int modCount = 0;

    public PriorityQueue(int initialCapacity, 
                         Comparator<? super E> comparator) {
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.queue = new Object[initialCapacity + 1];
        this.comparator = comparator;
    }

          从这里我们看到其内部是通过数组来实现存储,构造函数,默认初始化一个queue,下边我们通过添加一条数据来看看为什么称为优先级队列,

    增加一条数据,

    public boolean offer(E o) {
        if (o == null)
            throw new NullPointerException();
        modCount++;
        ++size;

        // Grow backing store if necessary
        if (size >= queue.length) 
            grow(size);

        queue[size] = o;
        fixUp(size);
        return true;
    }

 

    关键看fixUp这个函数,

    private void fixUp(int k) {
        if (comparator == null) {
            while (k > 1) {
                int j = k >> 1;
                if (((Comparable<E>)queue[j]).compareTo((E)queue[k]) <= 0)
                    break;
                Object tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
                k = j;
            }
        } else {
            while (k > 1) {
                int j = k >>> 1;
                if (comparator.compare((E)queue[j], (E)queue[k]) <= 0)
                    break;
                Object tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
                k = j;
            }
        }
    }

 首先判断是否有实现的comparator接口的函数,如果没有说明默认为实现Comparable接口,然后用折半查找进行排序,否则就是用实现了Comparator接口的类进行比较,现在我们

 知道了如果使用PriorityQueue,其加入的类应该实现Comparable接口,或者提供一个Comparator比较器,默认String会安装首字母顺序排序。

 从队列中删除一条记录,poll():

    public E poll() {
        if (size == 0)
            return null;
        modCount++;

        E result = (E) queue[1];
        queue[1] = queue[size];
        queue[size--] = null;  // Drop extra ref to prevent memory leak
        if (size > 1)
            fixDown(1);

        return result;
    }

 

关键方法fixDown,看一下其实现:

    private void fixDown(int k) {
        int j;
        if (comparator == null) {
            while ((j = k << 1) <= size && (j > 0)) {
                if (j<size && 
                    ((Comparable<E>)queue[j]).compareTo((E)queue[j+1]) > 0)
                    j++; // j indexes smallest kid

                if (((Comparable<E>)queue[k]).compareTo((E)queue[j]) <= 0)
                    break;
                Object tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
                k = j;
            }
        } else {
            while ((j = k << 1) <= size && (j > 0)) {
                if (j<size && 
                    comparator.compare((E)queue[j], (E)queue[j+1]) > 0)
                    j++; // j indexes smallest kid
                if (comparator.compare((E)queue[k], (E)queue[j]) <= 0)
                    break;
                Object tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
                k = j;
            }
        }
    }

 

 跟添加逻辑是相似的,需要对现有数据进行重新排序。

 

3 典型案例

 

 我们通过一个例子来看看PriorityQueue的应用:

 

Person类:

public class Person implements Comparable{
	

	private String name;
	private String age; 
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	public int compareTo(Object o) {
		
		return this.age.compareTo(((Person)o).getAge());
	}
	
	

}

 

主调用类:

public class QueueTest {

	public static void main(String[] args) {

		Queue<Person> queue = new PriorityQueue<Person>();
		 Person p = new Person();
		 p.setAge("23");
		 Person p1 = new Person();
		 p1.setAge("34");
		 Person p2 = new Person();
		 p2.setAge("12");
		 
		 Person p3 = new Person();
		 p3.setAge("12");
		 Person p4 = new Person();
		 p4.setAge("83");
		 
		 queue.offer(p);
		 queue.offer(p1);
		 queue.offer(p2);
		 queue.offer(p3);
		 queue.offer(p4);
		 
		 while(!queue.isEmpty()){
			 
			 System.out.print(queue.poll().getAge()+" ");
			
		 }
			}

}

 打印结果:

12 12 23 34 83 

 

4 总结

本人在实际项目中从未使用过Queue,但是其思想可以为我们所用,优先级队列在插入和删除的时候,需要重新排序,会有一定的性能损失。大家有没有在实际项目中应用Queue,

有的话,可以留言进行讨论,谢谢。 

  • 大小: 7.8 KB
  • 大小: 18.8 KB
8
1
分享到:
评论
5 楼 askyuan 2010-04-20  
UML图画的很漂亮呀,呵呵
4 楼 huatu122 2010-04-19  
你的uml类图很美啊
3 楼 masterzs 2010-04-12  
jerryfeng 写道
看样子,象是在IDEA里面用yfiles出的图
http://www.yworks.com/en/products_yfiles_about.html
因为那图左下角写着的Powered by yFiles
很久没用IDEA了,不过Interface/Class的图标我还认得

That's correct
2 楼 jerryfeng 2010-04-12  
看样子,象是在IDEA里面用yfiles出的图
http://www.yworks.com/en/products_yfiles_about.html
因为那图左下角写着的Powered by yFiles
很久没用IDEA了,不过Interface/Class的图标我还认得
1 楼 palmelf 2010-04-11  
你用的uml画图工具是什么? 很漂亮的。

相关推荐

    JDK容器学习之Queue:LinkedBlockingQueue

    JDK容器学习之Queue:LinkedBlockingQueue

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

     《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 书籍 计算机书籍  《java jdk 7学习笔记》是作者多年来教学实践经验的总结...

    Java并发包源码分析(JDK1.8)

    Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...

    delay-queue:JDK实现的本地delayQueue和基于分布式Redis的两种分布式

    delay-queue local delayQueue implemented by JDK & two kinds of distributed delayQueue based redis 1. 基本介绍 RedisSynDelayQueue 基于redis,并发情况下会加分布式锁,单线程场景(syn=false)性能较好, ...

    Chronicle-Queue-Demo:编年史队列的示例程序

    确保拥有适用于Java 8的JDK,可以使用 。 打开Intelij或您的 ,如果尚未, 。 本教程使用Intelij。 Check out from Version Control ”中Check out from Version Control并选择Git ,打开“ Clone Repository 。 在...

    leetcode分类-architects-corner:建筑师的角落

    Queue Java Java版 JDK X 中发布的功能 JDK 8 和 JDK 9 JDK 8 和 9 JDK 9 JDK 9 JDK9 的 55 个新特性 JDK 10 JDK 10 JDK 9、10 和 11 JDK 10 JDK 10 JDK 10 JDK 11 JDK 11 Java 堆栈 名称 描述 关联 碲 Tellurium ...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    jdk logger 测试框架 测试框架 junit easymock testng mockito bug管理 禅道 jira 开发工具 编程工具 eclipse myeclipse idea vi VS webstorm sublime text 版本控制 svn git 项目管理 ...

    springmvc整合activemq消息队列Demo

    该demo在本地启动activemq后放在tomcat中可直接运行,不需要修改配置,连接远程的activemq需要手动修改applicationContext.xml中的activemq连接地址,jdk1.8

    线程-线程池-锁-集合-Map-队列.docx

    线程是系统中可执行调度的最小单位。线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,规避资源耗尽...集合的详细描述,以及集合中的异同点,HashMap不同jdk版本区别,ConcurrentHashMap介绍。

    使用多线程模拟MQ系统应用

    环境:Windows XP SP3、JDK 1.6 使用说明: 1.javac DemoMQ.java 2.java DemoMQ 说明:本人在给Java游戏开发特训班讲解多线程时,需要说明多线程同步的问题,其中讲解了使用“生产者-消费者”模型来解决同步问题。...

    javabiginteger源码-SoftwareEngineerChallenge:软件工程师挑战赛

    JDK 中包含了很多不可变类,包括String、装箱的原始类、BigInteger 等。基本上不可变类是不太容易出错的。 请使用以下 api 实现不可变队列: Scala版本: trait Queue [ T ] { def isEmpty : Boolean def enQueue ( ...

    廖雪峰 Java 教程.doc

    使用Queue 使用PriorityQueue 使用Deque 使用Stack 使用Iterator 使用Collections IO File对象 InputStream OutputStream Filter模式 操作Zip 读取classpath资源 序列化 Reader Writer PrintStream...

    disruptor-3.4.2.jar 及 disruptor-3.4.2-sources.jar

    disruptor-3.4.2.jar 工具jar包 及 disruptor-3.4.2-sources.jar, Disruptor它是一个开源的并发框架,并获得2011 Duke’s 程序框架创新奖,能够在无锁的情况下实现网络的Queue并发操作,是 log4j2 引用的 jar 包

    docs

    ConcurrentQueue ConcurrentStack .NET API 系统 班级 大批 动作 Func 例外 GC 特性最大生成 方法 收集(Int32) CollectionCount(Int32) GetGeneration(对象) GetTotalMemory(布尔) ...

    javalruleetcode-dsal:数据结构与算法个人整理

    Queue, Map ArrayList, LinkedList, Vector, CopyOnWriteArrayList HashMap JDK7, JDK8 ConcurrentHashMap JDK7, JDK8 HashTable, ThreadLocalMap, WeakHashMap Leetcode 刷题记录 栈实现队列、队列实现栈、猫狗队列...

    javabasics:在BARD中作为会话的一部分编写的示例Java代码

    可以使用诸如Netbeans,Eclipse之类的任何IDE 可以使用Notepad ++,JDK(从cmd运行)在ubuntu中的软件 安装java 用法 编译单个文件(矩形文件夹除外) 如果从Windows使用JDK,请使用以下命令 javac FileName.java...

    Redis客户端Redisson.zip

    Redisson 是基于Redis服务之上构建的分布式、可伸缩的Java数据结构,高级的Redis客户端。【redis官方推荐】Redisson 是使用熟悉的Java数据结构来发挥Redis的威力,基于lettuce Redis客户端和Netty 4 ,兼容 Redis...

    Java 基础核心总结 +经典算法大全.rar

    枚举和普通类-样枚举神秘之处 枚举类 I/O File 类 基础 IO 类和相关方法InputStream OutputStream Reader 类Writer 类 InputStream 及其子类 OutputStream 及其子类Reader 及其子类Writer 及其子类 注解 关于 ...

    java并发包&线程池原理分析&锁的深度化

    并发包 同步容器类 Vector与ArrayList区别 ...在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队 列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue。

    leetcode中文版-algorithm:leetcode一些示例代码

    最近看了很多题解深感国内大厂受硅谷白板编程之风所害, 纷纷搞起了算法面试题,在这里分享一些我做题的经验, 先声明我自己也是一个菜鸡,我个人的算法能力局限于 二分查找 快速排序 图搜索 生成树 skip-list 等...

Global site tag (gtag.js) - Google Analytics