「java队列设计」队列方法 java
本篇文章给大家谈谈java队列设计,以及队列方法 java对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
用java语言设计顺序循环队列类
代码如下:
import java.io.Serializable;
import java.util.Arrays;
public class LoopQueueT implements Serializable {
/**
* @Fields serialVersionUID : TODO
*/
private static final long serialVersionUID = -3670496550272478781L;
private int DEFAULT_SIZE = 10;
private int capacity;// 保存数组的长度
private Object[] elementData;// 定义一个数组用于保存循环队列的元素
private int front = 0;// 队头
private int rear = 0;// 队尾
// 以默认数组长度创建空循环队列
public LoopQueue() {
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
// 以一个初始化元素来创建循环队列
public LoopQueue(T element) {
this();
elementData[0] = element;
rear++;
}
/**
* 以指定长度的数组来创建循环队列
*
* @param element
* 指定循环队列中第一个元素
* @param initSize
* 指定循环队列底层数组的长度
*/
public LoopQueue(T element, int initSize) {
this.capacity = initSize;
elementData = new Object[capacity];
elementData[0] = element;
rear++;
}
// 获取循环队列的大小
public int size() {
if (isEmpty()) {
return 0;
}
return rear front ? rear - front : capacity - (front - rear);
}
// 插入队列
public void add(T element) {
if (rear == front elementData[front] != null) {
throw new IndexOutOfBoundsException("队列已满的异常");
}
elementData[rear++] = element;
// 如果rear已经到头,那就转头
rear = rear == capacity ? 0 : rear;
}
// 移除队列
public T remove() {
if (isEmpty()) {
throw new IndexOutOfBoundsException("空队列异常");
}
// 保留队列的rear端的元素的值
T oldValue = (T) elementData[front];
// 释放队列的rear端的元素
elementData[front++] = null;
// 如果front已经到头,那就转头
front = front == capacity ? 0 : front;
return oldValue;
}
// 返回队列顶元素,但不删除队列顶元素
public T element() {
if (isEmpty()) {
throw new IndexOutOfBoundsException("空队列异常");
}
return (T) elementData[front];
}
// 判断循环队列是否为空队列
public boolean isEmpty() {
// rear==front且rear处的元素为null
return rear == front elementData[rear] == null;
}
// 清空循环队列
public void clear() {
// 将底层数组所有元素赋为null
Arrays.fill(elementData, null);
front = 0;
rear = 0;
}
public String toString() {
if (isEmpty()) {
return "[]";
} else {
// 如果front rear,有效元素就是front到rear之间的元素
if (front rear) {
StringBuilder sb = new StringBuilder("[");
for (int i = front; i rear; i++) {
sb.append(elementData[i].toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
// 如果front = rear,有效元素为front-capacity之间、0-front之间的
else {
StringBuilder sb = new StringBuilder("[");
for (int i = front; i capacity; i++) {
sb.append(elementData[i].toString() + ", ");
}
for (int i = 0; i rear; i++) {
sb.append(elementData[i].toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
}
}
public static void main(String[] args) {
LoopQueueString queue = new LoopQueueString("aaaa", 3);
// 添加两个元素
queue.add("bbbb");
queue.add("cccc");
// 此时队列已满
System.out.println(queue);
// 删除一个元素后,队列可以再多加一个元素
queue.remove();
System.out.println("删除一个元素后的队列:" + queue);
// 再次添加一个元素,此时队列又满
queue.add("dddd");
System.out.println(queue);
System.out.println("队列满时的长度:" + queue.size());
// 删除一个元素后,队列可以再多加一个元素
queue.remove();
// 再次加入一个元素,此时队列又满
queue.add("eeee");
System.out.println(queue);
}
}
如何用Java和Redis设计一个高效的先入先出的队列
分析:
redis的list底层是多个ziplist结构组成的“双向”链表。中间部分还压缩了一下。
最外层是由两个哈希表构成的dict。
哈希表的get(key)时间复杂度为O(1),而且这个O(1)理论上不会因为所占内存的大小和元素数目所改变。list的出队列和入队操作也都是O(1)。
Java的队列时间复杂度也应为O(1)。
可不可以直接用redis的list做先进先出?
情况1,数据数量不多,可以用
情况2,数据量多,但存的数据是激活码这样简单值一类,可以用。
情况3,list存的是要获取数据的索引,大量数据的值已经存在redis的KV结构中。
这时候,如果数据每次获取下一个数据都要执行redis的hash查找(O(1))然后redis的list从头或者末尾出一个。经过网络IO返回,Java程序在用出来的key去请求redis去get(key) (O(1))。这里是两次网络IO或者进程间的IO。
这时候,可以不用redis的list存索引而只是用redis大的KV哈希结构存键值。用①Java的队列先进先出获取下一个key或者②使用预先规定好的键生成的规则,让键是有规则有顺序的,比如自增ID,然后每次获取都是ID++,而直接从redis.get(ID.next());来获取值。
最后一种就是最高效的办法,为了特殊场景的高效出队列而设计。但是如果只是一般的数据量,使用redis的list也未尝不可。
用java语言设计一个先进先先出的队列类
代码仅供参考,如有问题,欢迎追问!
Basket:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 定义装苹果的篮子
*
* @author stone
* @version 2013-05-21
*/
public class Basket {
// 篮子,能够容纳Integer.MAX_VALUE个苹果
BlockingQueueObject basket = new LinkedBlockingQueueObject(Integer.MAX_VALUE);
// 生产苹果,放入篮子
public void produce(Object obj) throws InterruptedException {
// put方法放入一个苹果,若basket满了,等到basket有位置
basket.put(obj);
}
// 消费苹果,从篮子中取走
public Object consume() throws InterruptedException {
// take方法取出一个苹果,若basket为空,等到basket有苹果为止(获取并移除此队列的头部)
return basket.take();
}
}
BaksetTest:
import org.apache.log4j.Logger;
public class BaksetTest {
static Logger logger = Logger.getLogger(BaksetTest.class);
static Basket basket = new Basket();
public static void main(String[] args) throws Exception {
try{
Consume con = new Consume(basket);
Thread thread = new Thread(con);
thread.start();
Integer num = 0;
while(true){//循环放入数据到队列
num++;
basket.produce(num);
Thread.sleep(1*1000);
if(num1000000) num =0;
}
} catch( Exception e ){
logger.error("error : ", e);
}
}
}
//消费线程,用来消费队列里堆积数据,此线程为阻塞状态
class Consume implements Runnable {
Logger logger = Logger.getLogger(BaksetTest.class);
Basket basket;
public Consume (Basket basket){
this.basket = basket;
}
@Override
public void run() {
try{
while(true){//等待从队列取出数据
System.out.println("取出:" + basket.consume());
}
} catch ( Exception e ){
logger.error("error : ", e);
}
}
}
java编程 设计队列类。(先进先出)
import java.util.Vector;
@SuppressWarnings({ "unchecked", "serial" })
public class Stat extends Vector {
public void push(Object x) {
super.add(x); // 向队尾添加组件
}
public Object pop() { // 队首元素出队(从队列删除)
Object x = super.elementAt(0); // 返回指定索引处的组件
super.removeElementAt(0); // 删除指定索引处的组件
return x;
}
public void remove() {
super.removeAllElements(); // removeAllElements()移除全部组件,并将其大小设置为零
}
public static void main(String[] args) throws java.io.IOException {
Stat s = new Stat();
s.push("123adfasf123");
s.push(123123132);
System.out.println(s.pop());
System.out.println(s.pop());
}
}
java队列设计的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于队列方法 java、java队列设计的信息别忘了在本站进行查找喔。