Какую реализацию очереди использовать в Java? - PullRequest
0 голосов
/ 17 апреля 2010

Мне нужно использовать структуру FIFO в моем приложении. В нем должно быть не более 5 элементов. Я хотел бы иметь что-то простое в использовании (мне все равно, для параллелизма), реализующее интерфейс Collection.

Я попробовал LinkedList, который, кажется, приходит из очереди, но он не позволяет мне установить его максимальную емкость. Такое ощущение, что я просто хочу максимум 5 элементов, но пытаюсь добавить 20, он просто будет увеличиваться в размере, чтобы соответствовать ему. Я хотел бы что-то, что будет работать следующим образом:

XQueue<Integer> queue = new XQueue<Integer>(5); //where 5 is the maximum number of elements I want in my queue.
for (int i = 0; i < 10; ++i) {
    queue.offer(i);
}

for (int i = 0; i < 5; ++i) {
    System.out.println(queue.poll());
}

Это напечатало бы:

5
6
7
8
9

Спасибо

Ответы [ 7 ]

3 голосов
/ 17 апреля 2010

Создайте свой собственный подкласс того, который вам нужен, и переопределите метод add так, чтобы он

  • проверяет, подойдет ли новый объект, и завершается неудачей, если нет
  • вызывает super.add ()

(и конструкторы).

Если вы хотите заблокировать его при вставке, если он заполнен, это другое дело.

2 голосов
/ 17 апреля 2010

Я не видел подобных ограничений в API. Вы можете использовать ArrayList, изменив поведение метода add с помощью функции анонимного класса:

new ArrayList<Object>(){
    public boolean add(Object o){ /*...*/ }
}
2 голосов
/ 17 апреля 2010

Похоже, вам нужна структура FIFO ограниченного размера, которая высвобождает самые старые элементы при добавлении новых. Я рекомендую решение, основанное на реализации циклического массива , где вы должны отслеживать индекс хвоста и заголовок очереди и увеличивать их (циклически) по мере необходимости.

EDIT: Вот моя реализация (обратите внимание, что это коллекция). Он отлично работает с вашим тестовым сценарием.

public class XQueue <T> extends AbstractQueue<T>{
    private T[] arr;
    private int headPos;
    private int tailPos;
    private int size;

    @SuppressWarnings("unchecked")
    public XQueue(int n){
        arr = (T[]) new Object[n];
    }

    private int nextPos(int pos){
        return (pos + 1) % arr.length;
    }

    @Override
    public T peek() {
        if (size == 0)
            return null;
        return arr[headPos];
    }

    public T poll(){
        if (size == 0)
            return null;
        size--;
        T res = arr[headPos];
        headPos = nextPos(headPos);     
        return res;
    }

    @Override
    public boolean offer(T e) {
        if (size < arr.length)
            size++;
        else
            if (headPos == tailPos)
                headPos = nextPos(headPos);
        arr[tailPos] = e;
        tailPos = nextPos(tailPos);
        return true;
    }

    @Override
    public Iterator<T> iterator() {
        return null; //TODO: Implement
    }

    @Override
    public int size() {
        return size;
    }
}
1 голос
/ 18 апреля 2010

Вы смотрели на библиотеку Apache Commons Collections ?BoundedFifoBuffer должно точно соответствовать вашим потребностям.

1 голос
/ 17 апреля 2010

У вас есть три варианта

1) Подкласс реферативной коллекции

2) Ограничьте размер до пяти и выполните логику вокруг кода, в котором вы делаете вставку.

3) Использовать LinkedListHashMap Метод removeEldestEntry (Map.Entry) может быть переопределен для наложения политики автоматического удаления устаревших сопоставлений при добавлении новых сопоставлений на карту. (Затем вы использовали бы Итератор для получения значений - которые будут возвращены в порядке вставки)

Ваша лучшая ставка # 1 - это очень легко, если вы посмотрите на ссылку.

1 голос
/ 17 апреля 2010

Возможно, ArrayBlockingQueue может сработать. Смотрите здесь . Попробуйте что-то вроде этого:

BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(5);

for (int i = 0; i < 10; i++) {
  while (!queue.offer(i)) {
    queue.poll();        
  }
}

for (int i = 0; i < 5; i++) {   
  System.out.println(queue.poll());
}
0 голосов
/ 22 марта 2014

Если я правильно помню, я сделал именно то, что вы хотите, используя LinkedList.

Что вам нужно сделать, это проверить размер списка, если он равен 5 и вы хотите добавить объекты, просто удалите первый элемент и продолжайте делать это, если размер равен 5.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...