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

猜你喜欢

转载自blog.csdn.net/weixin_39606236/article/details/84564754