如何"修剪"一个arrayList只有5个最近的值? :

时间:2014-09-06 06:53:18

标签: java arraylist

我将在类级别声明一个ArrayList。我将使用'set'方法用值填充arrayList。这个'set'方法将从ActionEvent方法调用。事件将在程序中定期发生,因此这种“set”方法将被调用100次或更多次。每次调用'set'时,它都会将String变量传递给set方法。 String变量将添加到(类级别)ArrayList。我希望这个ArrayList“修剪”自己,以便它只包含5个值。即:我需要消除索引4处的值,索引3处的值转移到索引4,传入的“最新”变量变为索引0.我不知道该怎么做使得ArrayList“以这种方式“修饰”。一些指导会非常赞赏。谢谢xxx

3 个答案:

答案 0 :(得分:3)

ArrayList并不适合您需要做的事情。你基本上需要有限的容量circular buffer - ArrayDeque会更接近。但是,您必须对其进行扩展,以便在达到其容量时隐式删除​​元素:

public static class LimitedArrayDeque<T> extends ArrayDeque<T> {
    int threshold;

    public LimitedArrayDeque(int capacity) {
        super(capacity);

        this.threshold = capacity - 1;
    }

    @Override
    public boolean add(T element) {
        while (this.size() > this.threshold) {
            this.removeFirst();
        }

        return super.add(element);
    }

    /* ... */
}

请注意,您应该覆盖以与我的示例中的add()相同的方式向队列添加元素的任何方法。

答案 1 :(得分:1)

来自Size-limited queue that holds last N elements in Java


Apache commons集合4有CircularFifoQueue这就是你要找的东西。 引用javadoc:

  

CircularFifoQueue是一个先进先出队列,具有固定大小,如果已满,则替换其最旧的元素。

如果您使用的是较旧版本的Apache commons集合(3.x),则可以使用CircularFifoBuffer,这与没有泛型的情况基本相同。

更新:在commons集合版本4发布后更新的答案

答案 2 :(得分:0)

  

我不知道该怎么做才能使ArrayList&#34; trim&#34;本身就是这样。一些指导将非常感激。

来自How to design a Least Recently Used (LRU) Cache in Java。但它不使用ArrayList

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class LRUCache<K, V> {

    //Maximum capacity for the LRU cache.
    private final int capacity;
    //Queue to store the recently used keys.
    private ConcurrentLinkedQueue<K> queue;
    //Key-Value store to maintain the actual object.
    private ConcurrentHashMap<K, V> map;

    /**
     * Initial capacity for the LRU Cache.
     * @param capacity
     */
    public LRUCache(final int capacity) {
        this.capacity = capacity;
        this.queue  = new ConcurrentLinkedQueue<K>();
        this.map    = new ConcurrentHashMap<K, V>(capacity);
    }

    /**
     * Check whether the items exists in the cache. Returns null if key doesn't exists in the cache.
     * @param key
     * @return 
     */
    public V get(final K key) {
        return map.get(key);
    }

    /**
     * Add new value to the LRU Cache. If the key already exists, 
     * the key will be promoted to the front of the cache.
     * Neither the key nor the value can be null.
     * @param key
     * @param value
     * @throws NullPointerException
     */
    public synchronized void put(final K key, final V value) {
        if(key == null || value == null) {
            throw new NullPointerException();
        }
        if (map.containsKey(key)) {
            queue.remove(key);
        }
        while (queue.size() >= capacity) {
            K expiredKey = queue.poll();
            if (expiredKey != null) {
                map.remove(expiredKey);
            }
        }
        queue.add(key);
        map.put(key, value);
    }
}

您还可以使用LinkedHashMap。但同样,它不是ArrayList

另见Pro Android Apps Performance Optimization。第1章,&#34;优化Java代码&#34 ;;关于&#34;缓存结果&#34;和LruCache<K, V>;和第4章,&#34;高效使用记忆&#34;。