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

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

Ответы

Ответ 1

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

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) делает.).

Справка:


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

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)

Справка:

Ответ 2

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

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

Ответ 3

Не с классами коллекций 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: Как указывает Пайло Эберманн, правильный ответ, когда элемент не добавлен, - это исключение.

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

Example 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

Ответ 7

вы можете установить начальную емкость некоторых коллекций. Я не думаю, что вы можете установить максимальный размер.

Вы можете построить эту логику в своих классах домена (бизнес-логику), чтобы обеспечить максимальный размер. Или вы можете создать подкласс....

Ответ 8

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

Ответ 9

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

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

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

Итак, в свою очередь, чтобы получить снова набор точно определенных 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); }    

     }

}

Ответ 10

Супер легко создать свой собственный класс, который расширяет коллекцию. Я просто сделал это для своей собственной ситуации, расширив 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);
    }

} 

Ответ 11

Вот мой собственный код для 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.");
    }
}