设置集合的最大大小的任何方法?

时间:2011-03-04 15:55:38

标签: java collections

有没有办法在Java中设置最大的集合大小?

11 个答案:

答案 0 :(得分:16)

你可以这样做:

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,这是一个静态方法,用于装饰具有最大大小的现有List

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方法一样)

<强>参考:

答案 1 :(得分:6)

ArrayBlockingQueueLinkedBlockingQueue都支持最大尺寸。 LinkedHashMap支持在达到最大尺寸时逐出最旧或最近最少使用的物品。

达到最大尺寸时,您希望它做什么?

答案 2 :(得分:4)

答案 3 :(得分:3)

您必须实现自己的Collection。此外,您的最大尺寸概念尚未完全定义。例如,您是否希望阻止添加新项目?放下最旧的物品?最新的项目?最大大小是属性,而不是行为。如果要实现这一点,则需要定义行为部分。

答案 4 :(得分:2)

如果您不介意外部库,可以使用Guava的EvictingQueue

srigalamilitan的{​​p> Example

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

答案 5 :(得分:1)

标准库中的大多数通用集合都没有硬容量 - 只需要最小的初始分配。我能想到的唯一例外是LinkedBlockingQueue。其他库有其他有界集合,如LRUCache

创建自己的包装器应该相当简单,如果这对你有用。

答案 6 :(得分:1)

超级轻松创建扩展Collection的自己的类。我只是为了自己的情况做了这个,扩展了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);
    }

} 

答案 7 :(得分:0)

您可以设置某些集合的初始容量。我不认为你可以设置最大尺寸。

您可以将该逻辑构建到域类(业务逻辑)中以强制执行最大大小。或者你可以创建一个子类....

答案 8 :(得分:0)

如果你的意思是“是否有一个方法在Collection接口(或它的标准实现)上你可以设置大小,答案是否。你能编写(或扩展)一个类的最大大小比你肯定可以。

答案 9 :(得分:0)

也许我有一个类似的案例,因为我想“调整”一组对象,我通过两个步骤检索:

  • 第一步通过sql查询检索N个已确定项目的集合(ROWNUM完成了这项工作)。

  • 第二步验证结果集合以最终得到另一个具有未确定大小的集合(可能是&lt;或=所有sql检索元素的大小)。

因此,为了从这个“CollectionOfValidatedObjects”中再次获得N个确定对象的集合,我做了以下内容:

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 :(得分:0)

这是我自己的一个最大大小的ArrayList代码,来自Matthew Gilliard的回答。它覆盖了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.");
    }
}