创建固定大小的堆栈

时间:2011-10-11 14:46:04

标签: java stack

我想用Java创建一个Stack,但要修改大小。例如,创建一个新的Stack,将大小设置为10,然后当我将项目推送到堆栈时它会填满,当它填充到10时,堆栈中的最后一个项目被推下(删除)。我想使用Stack,因为它使用LIFO并且非常符合我的需求。

但是Stack从Vector继承的setSize()方法似乎并没有实际限制Stack的大小。我想我错过了一些关于Stacks如何工作的东西,或者Stacks并不意味着受到限制所以这是不可能的。请教育我!

8 个答案:

答案 0 :(得分:23)

以下SizedStack类型扩展了Stack

import java.util.Stack;

public class SizedStack<T> extends Stack<T> {
    private int maxSize;

    public SizedStack(int size) {
        super();
        this.maxSize = size;
    }

    @Override
    public T push(T object) {
        //If the stack is too big, remove elements until it's the right size.
        while (this.size() >= maxSize) {
            this.remove(0);
        }
        return super.push(object);
    }
}

像这样使用它:SizedStack<Float> mySizedStack = new SizedStack<Float>(10);。除了大小之外,它的运作方式与其他任何Stack一样。

答案 1 :(得分:5)

您可以创建一个非常简单的堆栈:

public class FixedStack<T>
{
    private T[] stack;
    private int size;
    private int top;

    public FixedStack<T>(int size)
    {
        this.stack = (T[]) new Object[size];
        this.top = -1;
        this.size = size;
    }

    public void push(T obj)
    {
        if (top >= size)
            throw new IndexOutOfBoundsException("Stack size = " + size);
        stack[++top] = obj;
    }

    public T pop()
    {
        if (top < 0) throw new IndexOutOfBoundsException();
        T obj = stack[top--];
        stack[top + 1] = null;
        return obj;
    }

    public int size()
    {
        return size;
    }

    public int elements()
    {
        return top + 1;
    }
}

答案 2 :(得分:1)

纯堆栈不会限制它的大小,因为堆栈解决的许多问题你不知道你需要多少元素。

您可以编写一个自定义堆栈来实现您描述的需求。但是,如果你这样做,你将打破LIFO。如果满足最大尺寸,并且您在堆栈上推送新内容,则只会丢失先前添加的项目。所以,如果你开始从你的堆栈中弹出项目,你会错过一些。

答案 3 :(得分:1)

LinkedBlockingDeque是一个简单的选项。使用LinkedBlockingQueue(int)构造函数,其中参数是您的堆栈限制。


正如您所观察到的,StackVector模拟了无界序列。 setSize()方法截断堆栈/向量。它不会阻止数据结构超出该大小。

答案 4 :(得分:1)

这不是不可能的:)你只需要提供自己的实现。

我会从像this这样的RingBuffer开始,并相应地调整它。

答案 5 :(得分:0)

您可以继承Stack并覆盖相应的方法来实现此自定义行为。并确保给它一个明确的名称(例如FixedStack)。

答案 6 :(得分:0)

您需要的是像LinkedList这样的双端队列。这不会自动删除前面的元素,但通过子类化/装饰它可以添加该功能。

答案 7 :(得分:0)

您可以使用LinkedHashMap并覆盖其removeEldestEntry方法:

public class FixedStack extends LinkedHashMap<Long, String> {

    private final int capacity;

    public FixedStack(int capacity) {
        this.capacity = capacity;
    }

    @Override
    protected boolean removeEldestEntry(final Map.Entry<Long, String> eldest) {
        return super.size() > capacity;
    }
}

并测试它:

    public static void main(String[] args) {

        FixedStack stack = new FixedStack(10);

        long added = 0;
        for (Locale locale : Locale.getAvailableLocales()) {
            if (locale.getDisplayCountry().length() > 0) {
                stack.put(added, locale.getDisplayCountry());
                System.out.println(locale.getDisplayCountry());
                added++;
            }
        }
        System.out.println(String.format(">>>>>>>>> %s added",
                added));
        Iterator<Entry<Long, String>> iterator = stack.entrySet().iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next().getValue());
        }
    }

您只需要决定要用作什么键,我在示例中使用了一个简单的计数器。