2011-04-01 67 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); 
    } 
}