Любой способ установить максимальный размер коллекции? - PullRequest
21 голосов
/ 04 марта 2011

Есть ли способ установить максимальный размер коллекции в Java?

Ответы [ 11 ]

17 голосов
/ 04 марта 2011

Вы можете сделать это:

List<X> list = Arrays.asList(new X[desiredSize]);
// where X is any Object type (including arrays and enums,
// but excluding primitives)

Полученный список можно изменять, но нельзя изменять его размер (т. Е. add(e) и remove(e) неработает, но set(index, e) делает).

Ссылка:


Или: используя Гуава , вот статический метод, который украшает существующий список с максимальным размером

public static <T> List<T> setMaxSize(
    final List<T> input, final int maxSize){

    return new ForwardingList<T>(){

        @Override
        public boolean addAll(Collection<? extends T> collection){
            return standardAddAll(collection);
        }

        @Override
        public boolean addAll(int index, Collection<? extends T> elements){
            return standardAddAll(index, elements);
        }

        public boolean add(T e) {
            checkMaxSize();
            return delegate().add(e);
        }

        @Override
        public void add(final int index, final T e){
            checkMaxSize();
            delegate().add(index, e);
        }

        private void checkMaxSize(){
            if(size() >= maxSize){
                throw new UnsupportedOperationException("Maximum Size "
                    + maxSize + " reached");
            }
        }

        @Override
        protected List<T> delegate(){
            return input;
        }
    };
}

Поскольку классы ForwardingXxx существуют для всех стандартных коллекцийтипы, вы можете написать себе аналогичные декораторы и для других коллекций.

Очевидно, это будет работать, только если ваш клиентский код использует декорированную коллекцию.Если вы изменяете базовую коллекцию, которую вы ввернули (как методы Collections.unmodifiableXXX)

Ссылка:

6 голосов
/ 04 марта 2011

ArrayBlockingQueue и LinkedBlockingQueue поддерживают максимальный размер.LinkedHashMap поддерживает удаление самых старых или наименее недавно использованных предметов при достижении максимального размера.

Что вы хотите сделать, когда будет достигнут максимальный размер?

4 голосов
/ 04 марта 2011

Не для классов java.util коллекций, но для любой конкретной коллекции вы можете расширить ее и переопределить .add() или .put() для своих собственных целей. Примерно так будет работать для списка:

public final boolean add(E e) {
    if (this.size() == MAX_SIZE){
        throw new IllegalStateException("List is already at maximum size of " + MAX_SIZE);
    }
    super.add(e);
}

JavaDoc говорит IllegalStateExeption правильно"если элемент не может быть добавлен в настоящее время из-за ограничений вставки".

Редактировать: Как указывает Стас Курилин ниже, вам следует быть осторожным, чтобы переопределить все методы, которые могут добавить что-то в коллекцию, например .addAll() .

Редактировать 2: Когда Паŭло Эберманн указывает ниже, правильный ответ, если элемент не добавлен, - выбросить исключение.

3 голосов
/ 04 марта 2011

Вы должны реализовать свою собственную коллекцию. Кроме того, Ваше понятие максимального размера не полностью определено. Например, хотите ли вы предотвратить добавление новых элементов? Отбросить самый старый предмет? Самый новый предмет? Максимальный размер - это атрибут, а не поведение. Вам нужно определить часть поведения, если вы хотите это реализовать.

2 голосов
/ 13 июля 2017

Если вы не возражаете против внешней библиотеки, вы можете EvictingQueue .

от Guava.

Пример от srigalamilitan:

Queue<String> evictingQueue= EvictingQueue.create(10);
String message="This Is Evicting Queue ";

for (int i = 1; i <= 15; i++) {
    evictingQueue.add(message + i);
    System.out.println("EvictingQueue size: " + evictingQueue.size());
}

System.out.println("Poll Queue Evicting");
while(!evictingQueue.isEmpty()){
    println(evictingQueue.poll());
}

печать:

This Is Evicting Queue 6
This Is Evicting Queue 7
This Is Evicting Queue 8
This Is Evicting Queue 9
This Is Evicting Queue 10
This Is Evicting Queue 11
This Is Evicting Queue 12
This Is Evicting Queue 13
This Is Evicting Queue 14
This Is Evicting Queue 15
1 голос
/ 29 октября 2015

Супер легко создать свой собственный класс, расширяющий коллекцию. Я просто сделал это для моей собственной ситуации, расширив HashSet:

import java.util.HashSet;

public class LimitedHashSet<E> extends HashSet<E> {
    private static final long serialVersionUID = -23456691722L;
    private final int limit;

    public LimitedHashSet(int limit) {
        this.limit = limit;
    }

    @Override
    public boolean add(E object) {
        if (this.size() > limit) return false;
        return super.add(object);
    }

} 
1 голос
/ 04 марта 2011

Большинство коллекций общего назначения в стандартной библиотеке НЕ имеют жесткой емкости - только минимальное начальное распределение. Единственное исключение, которое я могу придумать, - это LinkedBlockingQueue. Другие библиотеки имеют другие ограниченные коллекции, такие как LRUCache.

Это должно быть довольно просто создать свою собственную обертку, если это полезно для вас.

0 голосов
/ 29 декабря 2016

Вот мой собственный код для ArrayList с максимальным размером, собранный из ответа Мэтью Джиллиарда. Он переопределяет все три конструктора из ArrayList, а также переопределяет .AddAll().

import java.util.ArrayList;
import java.util.Collection;

public class MaxedArrayList<E> extends ArrayList<E> {
    final int MAXSIZE;

    public MaxedArrayList(int initialCapacity, final int MAXSIZE) {
        super(initialCapacity);
        this.MAXSIZE = MAXSIZE;
    }

    public MaxedArrayList(final int MAXSIZE) {
        super();
        this.MAXSIZE = MAXSIZE;
    }

    public MaxedArrayList(Collection<? extends E> c, final int MAXSIZE) {
        super(c);
        this.MAXSIZE = MAXSIZE;
        sizeCheck();
    }

    private boolean sizeCheck() {
        //returns true if operation is legal.
        return (size() <= MAXSIZE);
    }

    private boolean sizeCheck(int deltaElements) {
        if (deltaElements < 0) throw new IllegalArgumentException();
        //returns true if operation is legal.
        return (size() + deltaElements <= MAXSIZE);
    }

    @Override
    public void add(int index, E element) throws IllegalStateException {
        if (!sizeCheck()) throw throwException();
        super.add(index, element);
    }

    @Override
    public boolean addAll(Collection<? extends E> c) throws IllegalStateException {
        if (!sizeCheck(c.size())) throw throwException();
        return (super.addAll(c));
    }

    private IllegalStateException throwException() {
        return new IllegalStateException("Request is over MaxArrayList max size. Elements not added.");
    }
}
0 голосов
/ 11 октября 2011

Возможно У меня был сопоставимый случай, так как я хотел «изменить размер» коллекции объектов, которую я извлек за два шага:

  • Получен первый шагСбор из N определенных элементов с помощью SQL-запроса (ROWNUM выполнил задание).

  • Второй этап проверки результирующей коллекции, чтобы получить в итоге другую коллекцию с неопределенным размером (может быть <или = размервсе sql-извлеченные элементы). </p>

Поэтому, в свою очередь, чтобы снова получить коллекцию точно N определенных объектов из этого «CollectionOfValidatedObjects», я сделал следующее:

public Collection<Object> determineSomeElements(int maxSize){    


     Collection<Object> returnValues = new ArrayList<Object>();

      // the initial collection with all retrieved validated elements
     Collection<Object> myValidatedCollection = getValidatedCollection();

     Iterator<Object> it = myValidatedCollection.iterator();


     // iterate and add a condition with the passed size
     while(it.hasNext() && returnValues.size() < maxSize) {

           returnValues.add(it.next); }    

     }

}

0 голосов
/ 04 марта 2011

Если вы имеете в виду «есть ли метод на интерфейсе Collection (или его стандартные реализации), где вы можете установить размер, ответом которого будет нет. Можете ли вы написать (или расширить) класс с максимальным размером, чем вы, конечно может.

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