萌新最近在练习队列,用猫狗队列练习一下
要求摘自https://www.cnblogs.com/xiyuan2016/p/6810256.html
用户可以调用add方法将cat类或者dog类的实例放入队列中;
用户可以调用pollAll方法,将队列中所有的实例按照队列的先后顺序依次弹出;
用户可以调用pollDog方法,将队列中dog类的实例按照队列的先后顺序依次弹出;
用户可以调用pollCat方法,将队列中cat类的实例按照队列的先后顺序依次弹出;
用户可以调用isEmpty方法,检查队列中是否还有dog和cat的实例;
用户可以调用isDogEmpty方法,检查队列中是否还有do的实例;
用户可以调用isCatEmpty方法,检查队列中是否还有cat的实例。
/**
* @author gaokuo
**/
public abstract class Animal {
/**
* 唯一标记
*/
private long stamp;
/**
* 类别
*/
private String type;
/**
* 名字
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getStamp() {
return stamp;
}
public void setStamp(long stamp) {
this.stamp = stamp;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public abstract void play();
/**
* 设置标记
* @param stamp 标记值
* @return this
*/
public Animal autoStamp(long stamp){
this.stamp = stamp;
return this;
}
}
/**
* @author gaokuo
**/
public class Cat extends Animal{
private Cat(String name) {
super();
setName(name);
setStamp(System.currentTimeMillis());
}
@Override
public void play() {
System.out.println(getName() + ":喵?");
}
public static Animal create(String name){
return new Cat(name);
}
}
/**
* @author gaokuo
**/
public class Dog extends Animal{
private Dog(String name) {
super();
setName(name);
setStamp(System.currentTimeMillis());
}
@Override
public void play() {
System.out.println(getName() + ":汪!");
}
public static Animal create(String name){
return new Dog(name);
}
}
实现:
import javax.management.OperationsException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 我要写一下猫狗队列
* @author gaokuo
**/
public class CatDogQueue {
private Queue<Animal> catQueue = new LinkedList<>();
private Queue<Animal> dogQueue = new LinkedList<>();
private AtomicLong stamp = new AtomicLong(0);
ReadWriteLock lock = new ReentrantReadWriteLock();
/**
* 用户可以调用add方法将cat类或者dog类的实例放入队列中
* @param animal 猫或狗
* @throws OperationsException 非空
* @throws IllegalArgumentException 类型为猫狗
*/
public void add(Animal animal) throws OperationsException,IllegalArgumentException {
if (animal == null){
throw new OperationsException("不支持添加空对象入队列");
}
lock.writeLock().lock();
try {
if (animal.getClass() == Cat.class){
catQueue.offer(animal.autoStamp(stamp.addAndGet(1L)));
}else if(animal.getClass() == Dog.class){
dogQueue.offer(animal.autoStamp(stamp.addAndGet(1L)));
}else{
throw new IllegalArgumentException("你只能添加猫或者狗!");
}
} finally {
lock.writeLock().unlock();
}
}
/**
* 用户可以调用pollAll方法,将队列中所有的实例按照队列的先后顺序依次弹出
* @return List<Animal> 先进先出的顺序
*/
public List<Animal> pollAll(){
lock.writeLock().lock();
List<Animal> animals = new ArrayList<>();
try {
while (true){
Animal cat = catQueue.peek();
Animal dog = dogQueue.peek();
if (cat == null && dog == null){
return animals;
}
if (cat == null){
animals.add(dogQueue.poll());
}else if(dog == null){
animals.add(catQueue.poll());
}else{
if (cat.getStamp() > dog.getStamp()){
animals.add(dogQueue.poll());
}else{
animals.add(catQueue.poll());
}
}
}
} finally {
lock.writeLock().unlock();
}
}
/**
* 用户可以调用pollDog方法,将队列中dog类的实例按照队列的先后顺序依次弹出
* @return List<Animal> 先进先出的顺序
*/
public List<Animal> pollDog(){
return getAnimals(dogQueue);
}
/**
* 用户可以调用pollCat方法,将队列中cat类的实例按照队列的先后顺序依次弹出
* @return List<Animal> 先进先出的顺序
*/
public List<Animal> pollCat(){
return getAnimals(catQueue);
}
/**
* 从队列中获取动物
* @param animalQueue 队列
* @return List<Animal> 动物列表
*/
private List<Animal> getAnimals(Queue<Animal> animalQueue) {
List<Animal> animals = new ArrayList<>();
lock.writeLock().lock();
try {
while (true){
Animal animal = animalQueue.peek();
if (animal == null){
return animals;
}
animals.add(animalQueue.poll());
}
} finally {
lock.writeLock().unlock();
}
}
/**
* 用户可以调用isEmpty方法,检查队列中是否还有dog和cat的实例
* @return boolean
*/
public boolean isEmpty(){
lock.readLock().lock();
try {
return catQueue.peek() == null && dogQueue.peek() == null;
} finally {
lock.readLock().unlock();
}
}
/**
* 用户可以调用isCatEmpty方法,检查队列中是否还有cat的实例
* @return boolean
*/
public boolean isCatEmpty(){
lock.readLock().lock();
try {
return catQueue.peek() == null;
} finally {
lock.readLock().unlock();
}
}
/**
* 用户可以调用isDogEmpty方法,检查队列中是否还有dog的实例
* @return boolean
*/
public boolean isDogEmpty(){
lock.readLock().lock();
try {
return dogQueue.peek() == null;
} finally {
lock.readLock().unlock();
}
}
}
测试:
import javax.management.OperationsException;
import java.util.List;
/**
* @author gaokuo
**/
public class Test {
public static void main(String[] args) throws OperationsException {
CatDogQueue catDogQueue;
System.out.println("------------------pollAll----------------------");
catDogQueue = getCatDogQueue();
List<Animal> animalsAll = catDogQueue.pollAll();
animalsAll.forEach(Animal::play);
System.out.println("--------------------pollDog--------------------");
catDogQueue = getCatDogQueue();
List<Animal> animalsDog = catDogQueue.pollDog();
animalsDog.forEach(Animal::play);
System.out.println("--------------------pollCat--------------------");
catDogQueue = getCatDogQueue();
List<Animal> animalsCat = catDogQueue.pollCat();
animalsCat.forEach(Animal::play);
System.out.println("--------------------isEmpty--------------------");
//全部弹出,此时队列猫狗都没有
catDogQueue.pollAll();
System.out.println(catDogQueue.isEmpty());
catDogQueue = new CatDogQueue();
catDogQueue.add(Dog.create("一狗子"));
System.out.println(catDogQueue.isEmpty());
System.out.println("--------------------isDogEmpty--------------------");
System.out.println(catDogQueue.isDogEmpty());
System.out.println("--------------------isCatEmpty--------------------");
System.out.println(catDogQueue.isCatEmpty());
}
/**
* 每次测试重置
*/
private static CatDogQueue getCatDogQueue() throws OperationsException {
CatDogQueue catDogQueue = new CatDogQueue();
catDogQueue.add(Dog.create("一狗子"));
catDogQueue.add(Cat.create("一猫子"));
catDogQueue.add(Dog.create("二狗子"));
catDogQueue.add(Dog.create("三狗子"));
catDogQueue.add(Cat.create("二猫子"));
return catDogQueue;
}
}
输出:
------------------pollAll----------------------
一狗子:汪!
一猫子:喵?
二狗子:汪!
三狗子:汪!
二猫子:喵?
--------------------pollDog--------------------
一狗子:汪!
二狗子:汪!
三狗子:汪!
--------------------pollCat--------------------
一猫子:喵?
二猫子:喵?
--------------------isEmpty--------------------
true
false
--------------------isDogEmpty--------------------
false
--------------------isCatEmpty--------------------
true