Создание стека фиксированного размера

Я хочу создать Stack в Java, но исправьте размер. Например, создайте новый Stack, установите размер 10, затем, когда я нажимаю элементы в стек, он заполняется, и когда он заполняет до десяти, последний элемент в стеке отбрасывается (удаляется). Я хочу использовать Stack, потому что он использует LIFO и очень хорошо соответствует моим потребностям.

Но метод setSize(), который Stack наследует от Vector, по-видимому, не ограничивает размер стека. Я думаю, что мне не хватает чего-то о том, как работают стеки, или, может быть, стеки не должны быть ограничены, поэтому это невозможно. Пожалуйста, просветите меня!

Ответ 1

Вы можете создать очень простой стек следующим образом:

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

Вот тип 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 the right size.
        while (this.size() >= maxSize) {
            this.remove(0);
        }
        return super.push(object);
    }
}

Используйте его так: SizedStack<Float> mySizedStack = new SizedStack<Float>(10); , Помимо размера, он работает как любой другой Stack.

Ответ 3

Чистый стек не ограничивал бы его размер, так как для многих проблем проблемы решаются, вы не знаете, сколько элементов вам понадобится.

Вы можете написать собственный стек, который реализует описанные вами потребности. Однако, если вы это сделаете, вы сломаете LIFO. Если максимальный размер выполнен, и вы нажимаете что-то новое в стеке, вы просто теряете ранее добавленный элемент. Поэтому, если вы затем начнете выскакивать предметы со своего стека, вы пропустите некоторые из них.

Ответ 4

LinkedBlockingDeque - один простой вариант. Используйте конструктор LinkedBlockingQueue(int) где параметр является вашим лимитом стека.


Как вы заметили, Stack и Vector моделируют неограниченные последовательности. Метод setSize() обрезает стек/вектор. Это не мешает росту структуры данных за пределами этого размера.

Ответ 5

Это не невозможно :) Вам просто нужно предоставить свою собственную реализацию.

Я бы начал с RingBuffer таким образом и соответствующим образом отрегулировал его.

Ответ 6

Вы можете подклассифицировать Stack и переопределить соответствующий метод для реализации этого пользовательского поведения. И не забудьте дать ему четкое имя (например, FixedStack).

Ответ 7

Вам нужна двойная очередь, такая как LinkedList. Это не будет автоматически удалять элементы на передней части, но, подклассифицируя/украшая его, вы можете добавить эту функциональность.

Ответ 8

Вы можете использовать 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());
        }
    }

Вам просто нужно решить, что вы хотите использовать в качестве ключа, я использовал простой счетчик в примере.