java佇列練習 - 貓狗佇列
阿新 • • 發佈:2018-11-27
萌新最近在練習佇列,用貓狗佇列練習一下
要求摘自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