2011-04-01 93 views
0

我想要一个数据结构(多线程环境)在Java中,可以容纳最多'n'元素。如果我添加(第n + 1)个元素,那么我应该用这个新元素替换最旧的元素。我知道我可以通过检查每个add()中的大小并以全尺寸进行替换操作来完成。但是,我想知道是否有任何Java库中的数据结构。请帮助在java中的固定大小的数据结构

回答

3

尝试使用固定大小的数组,并使用索引模数大小进行添加。这就是所谓的圆形阵列,Wikipedia有关于这个问题的体面的文章。

基本上,你跟踪一个索引,你应该写下一个条目,让这个索引环绕缓冲区大小,然后当你继续写时,你会覆盖最老的条目。

事情是这样的:

Object[] ring = new Object[32]; 
int writeIndex = 0; 

public void add(Object o) { 
    ring[writeIndex % ring.length] = o; 
    writeIndex++; 
} 
+0

这将在多线程环境中失败。 – jmg 2011-04-01 10:39:38

+0

@jmg;只有当周围环境没有考虑多线程时(如果你不知道如何执行多线程,java.util.HashMap也会在多线程环境中失败)。无论哪种方式,它并不是要逐字复制,而是要表明原则。 – falstro 2011-04-01 13:24:05

2

根据您的需要,一种方法是包装LinkedHashMap的子类。

import java.util.AbstractSet; 
import java.util.Iterator; 
import java.util.LinkedHashMap; 

public class FixedSizeSet<E> extends AbstractSet<E> { 
    private final LinkedHashMap<E, E> contents; 

    FixedSizeSet(final int maxCapacity) { 
     contents = new LinkedHashMap<E, E>(maxCapacity * 4 /3, 0.75f, false) { 
      @Override 
      protected boolean removeEldestEntry(java.util.Map.Entry<E, E> eldest) { 
       return size() == maxCapacity; 
      } 
     };  
    } 

    @Override 
    public Iterator<E> iterator() { 
     return contents.keySet().iterator(); 
    } 

    @Override 
    public int size() { 
     return contents.size(); 
    } 

    public boolean add(E e) { 
     boolean hadNull = false; 
     if (e == null) { 
      hadNull = contents.containsKey(null); 
     } 
     E previous = contents.put(e, e); 
     return e == null ? hadNull : previous != null; 
    } 

    @Override 
    public boolean contains(Object o) { 
     return contents.containsKey(o); 
    } 
}