Parsing Java priorityqueue Priority queue structure source code and usage _java

Source: Internet
Author: User
Tags anonymous comparable int size rand java anonymous class

Data structure of Priorityqueue

The data structure of the Priorityqueue (priority queue) in JDK7 is a two-fork heap. A minimal heap, to be exact.

The two-fork heap is a special heap, which is approximate to a completely binary tree. The binary heap satisfies the characteristic: the parent node's key value always maintains the fixed order relation to any one child node's key value, and each node's Saozi right subtree is a binary heap.
The maximum heap when the parent node's key value is always greater than or equal to the key value of any one child node. The minimum heap when the parent node's key value is always less than or equal to the key value of any one child node.
The figure below is a maximum heap

The Priorityqueue team head is the smallest element in the given order.

Priorityqueue objects that do not allow null values and do not support non-comparable. Priorityqueue requires that the objects be sorted using the comparable and comparator interfaces, and that the elements are processed according to priority in the sort.

The size of the Priorityqueue is unrestricted (unbounded), but the initial size can be specified at creation time. When the queue element is added, the queue is automatically enlarged.

Priorityqueue are not thread-safe, and similar priorityblockingqueue are thread-safe.

We know that queues follow a first-in, first-out (first-in-first-out) pattern, but there are times when you need to process objects in a queue based on priority. For example, let's say we have an application that generates a stock report during a daily trading session, which involves processing a lot of data and spending a lot of processing time. When the customer sends the request to the application, it actually goes into the queue. We need to first deal with the priority customers and then deal with ordinary users. In this case, the Java Priorityqueue (priority queue) can be helpful.

Priorityqueue is an unbounded queue based on the precedence heap, which can be sorted by default or by the provided comparator (comparer) when the queue is instantiated.
The precedence queue does not allow null values and does not support non-comparable (not comparable) objects, such as user-defined classes. Precedence queues require that objects be sorted by using the Java comparable and comparator interfaces, and that the elements are processed according to priority in the sort.

The header of the precedence queue is the smallest element that is based on natural sorting or comparator sorting. If you have multiple objects that have the same sort, you might randomly take any of them. When we get the queue, we return the header object of the queue.

The size of the priority queue is unrestricted, but you can specify an initial size when you create it. When we add elements to the priority queue, the queue size automatically increases.

Priorityqueue is not thread-safe, so Java provides priorityblockingqueue (implementing the Blockingqueue Interface) for Java multithreaded environments.

Second, priorityqueue source analysis

Members:

PRIAVTE transient object[] queue;
private int size = 0;

1.PriorityQueue construction of the small top heap process

Here we use the Priorityqueue constructor to pass a container as the parameter Priorityqueue (collecntion<? extends e> Example:

The process of constructing a small top heap is generally divided into two steps:

Copy container data to check whether the container data is null

private void Initelementsfromcollection (COLLECTION< extends e> c) {
  object[] a = C.toarray ();
  If C.toarray incorrectly doesn ' t return object[], copy it.
  if (A.getclass ()!= object[].class)
    a = arrays.copyof (A, a.length, object[].class);
  int len = a.length;
  if (len = = 1 | | | this.comparator!= NULL) for
    (int i = 0; i < len; i++)
      if (a[i] = null)
        throw new Nullpoin Terexception ();
  This.queue = A;
  This.size = a.length;
}

Adjust to make the data meet the structure of the small top heap.
First, we introduce two adjustment methods Siftup and Siftdown

Siftdown: When given an initialization element, adjust the element so that it satisfies the structural nature of the minimum heap. So keep going from top to bottom to compare and exchange the key values of element x with the child until you find the key value of element x that is less than or equal to the child's value (that is, it guarantees that it is smaller than its left and right node), or drops down to the leaf node.
For example, the following diagram, adjust 9 this node:

private void siftdowncomparable (int k, E x) {
  comparable<? super e> key = (comparable<? super e>) x;
  int half = size >>> 1;    SIZE/2 is the first leaf node of the subscript
  //As long as not to the leaf nodes while
  (K < half) {
    int child = (k << 1) + 1;//left child
    Object C = Qu Eue[child];
    int right = child + 1;
    Find the right
    < size &&
      ((comparable<. Super e>) c) of the child or children. CompareTo ((E) queue[right]) > 0)
      c = Queue[child = right];
    if (Key.compareto ((E) c) <= 0) break
      ;
    QUEUE[K] = C;
    K = child;
  }
  QUEUE[K] = key;
}

Siftup:priorityqueue inserts new elements into the tail each time a new element is added. Therefore, there should be the same adjustment process with the Siftdown, but only from the bottom (leaf) upward adjustment.
For example, the following schematic, fill in the Key 3 node:

private void siftupcomparable (int k, E x) {
  comparable<? super e> key = (comparable<? super e>) x;
  while (k > 0) {
    int parent = (k-1) >>> 1;   Get parent subscript
    Object e = queue[parent];
    if (Key.compareto ((e) e) >= 0) break
      ;
    Queue[k] = e;
    K = parent;
  }
  QUEUE[K] = key;
}

The whole process of building a small heap is:

private void Initfromcollection (COLLECTION< extends e> c) {
    initelementsfromcollection (c);
    Heapify ();
  }

Among them heapify is the process of siftdown.

2.PriorityQueue Capacity Expansion Process

As can be seen from the instance members, Priorityqueue maintains a object[], so its expansion mode and order table ArrayList difference.
Here only gives the source of the Grow method

private void Grow (int mincapacity) {
    int oldcapacity = queue.length;
    Double size if small; else grow by 50%
    int newcapacity = oldcapacity + (Oldcapacity <)?
                     (Oldcapacity + 2):
                     (oldcapacity >> 1));
    Overflow-conscious Code
    if (newcapacity-max_array_size > 0)
      newcapacity = hugecapacity (mincapacity);
    Queue = arrays.copyof (queue, newcapacity);
  }

As can be seen, when the capacity of the array is not large, each expansion is not small. When the size of the array is greater than 64, double the expansion at a time.

Third, the application of Priorityqueue

EG1:
here is a simple application: from the Dynamic Data to the K-large number.
The idea is to maintain a small top heap of size = K.

  Data is a Dynamic Data
  //heap The heap that maintains dynamic data
  //res used to hold the value of K large public
  boolean kthlargest (int data, int k, priorityqueue< Integer> Heap, int[] Res {
    if (Heap.size () < K) {
      heap.offer (data);
      if (heap.size () = = k) {
        res[0] = Heap.peek ();
        return true;
      }
      return false;
    }
    if (Heap.peek () < data) {
      heap.poll ();
      Heap.offer (data);
    }
    Res[0] = Heap.peek ();
    return true;
  }


EG2:
we have a customer class customer and it does not provide any sort of type. When we use it to establish a precedence queue, we should provide it with a comparer object.

Customer.java

Package com.journaldev.collections;
 
public class Customer {
 
  private int id;
  private String name;
 
  Public Customer (int i, String n) {
    this.id=i;
    this.name=n;
  }
 
  public int getId () {return
    ID;
  }
 
  Public String GetName () {return
    name;
  }
 
}

We use Java random numbers to generate random user objects. For natural ordering, we use an integer object, which is also a encapsulated Java object.
Here is the final test code that shows how to use Priorityqueue:

Priorityqueueexample.java

Package com.journaldev.collections;
Import Java.util.Comparator;
Import Java.util.PriorityQueue;
Import Java.util.Queue;
 
Import Java.util.Random; public class Priorityqueueexample {public static void main (string[] args) {//Priority queue Natural ordering example QUEUE&LT;INTEGER&G T
    Integerpriorityqueue = new priorityqueue<> (7);
    Random rand = new Random ();
    for (int i=0;i<7;i++) {Integerpriorityqueue.add (New Integer (Rand.nextint (100)));
      for (int i=0;i<7;i++) {Integer in = Integerpriorityqueue.poll ();
    SYSTEM.OUT.PRINTLN ("Processing Integer:" +in);
    }//Priority queue Use example queue<customer> customerpriorityqueue = new priorityqueue<> (7, Idcomparator);
 
    Adddatatoqueue (Customerpriorityqueue);
 
  Polldatafromqueue (Customerpriorityqueue); }//anonymous Comparator implementation public static comparator<customer> Idcomparator = new comparator<customer> () {@ Override public int Compare (customer C1, customer C2) {return (int) (C1.getid ()-C2.getid ());
 
  }
  };  Common method for adding data to queues private static void Adddatatoqueue (Queue<customer> customerpriorityqueue) {Random rand = new
    Random ();
      for (int i=0; i<7; i++) {int id = rand.nextint (100);
    Customerpriorityqueue.add (new Customer (ID, "Pankaj" +id)); }//Common method for fetching data from queues private static void Polldatafromqueue (Queue<customer> customerpriorityqueue) {while (true)
      {Customer cust = Customerpriorityqueue.poll ();
      if (cust = null) break;
    SYSTEM.OUT.PRINTLN ("Processing Customer with Id=" +cust.getid ());
 }
  }
 
}

Note that I use the Java anonymous class that implements the comparator interface and implement an id-based comparer.
When I run the above test program, I get the following output:

Processing integer:9
processing integer:16
processing integer:18
processing integer:25
Processing integer:33
processing integer:75
processing integer:77 processing
Customer with id=6
processing Customer with id=20
processing customer and id=24
processing customer with id=28
processing customer with id=29
processing customer with id=82
processing customer with id=96

It is clear from the output result that the smallest element is first taken out of the queue's head. If comparator is not implemented, ClassCastException is thrown when the customerpriorityqueue is established.

Exception in thread "main" Java.lang.ClassCastException:com.journaldev.collections.Customer cannot is cast to Java.lang . Comparable at
  java.util.PriorityQueue.siftUpComparable (priorityqueue.java:633)
  at Java.util.PriorityQueue.siftUp (priorityqueue.java:629) at
  Java.util.PriorityQueue.offer (Priorityqueue.java : 329) at
  Java.util.PriorityQueue.add (priorityqueue.java:306)
  at Com.journaldev.collections.PriorityQueueExample.addDataToQueue (priorityqueueexample.java:45) at
  Com.journaldev.collections.PriorityQueueExample.main (PRIORITYQUEUEEXAMPLE.JAVA:25)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.