1. 程式人生 > >java佇列練習 - 貓狗佇列

java佇列練習 - 貓狗佇列

萌新最近在練習佇列,用貓狗佇列練習一下

要求摘自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