Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 245|回复: 0

[集合学习]JDK学习之Queue

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-30 23:55:50 | 显示全部楼层 |阅读模式
    今天学习Queue,基本数据类型,特点先进先出(FIFO)。 1.JDK中接口的定义:

              在jdk里边,LinkedList直接实现的Queue接口,所以我们可以使用LinkedList来模拟Queue,看一下几个     主要方法: 2,主要方法解析:     加入一条记录,offer(E o)     public boolean offer(E o) {
            return add(o);
        }[/code]          可以看到内部默认调用LinkedList的add方法,也就是默认放到队尾,head的previous指向,     取出一条记录,     public E poll() {
            if (size==0)
                return null;
            return removeFirst();
        }[/code]     调用LinkedList的removeFirst方法,再看这个方法的实现:  public E removeFirst() {
            return remove(header.next);
        }[/code]     结果就是删除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;
        }[/code]           从这里我们看到其内部是通过数组来实现存储,构造函数,默认初始化一个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;
        }[/code]     关键看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;
                }
            }
        }[/code]  首先判断是否有实现的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;
        }[/code] 关键方法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;
                }
            }
        }[/code]  跟添加逻辑是相似的,需要对现有数据进行重新排序。 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());
            }
           
           
    }[/code] 主调用类: 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()+" ");
                           
                     }
                            }
    }
                            [/code]  打印结果: 12 12 23 34 83 [/code] 4 总结 本人在实际项目中从未使用过Queue,但是其思想可以为我们所用,优先级队列在插入和删除的时候,需要重新排序,会有一定的性能损失。大家有没有在实际项目中应用Queue, 有的话,可以留言进行讨论,谢谢。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-19 00:31 , Processed in 0.402866 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表