2015-07-03 58 views
5

我正在尋找一個java.util.Queue實現,該元素最多排隊一次相等的元素。java.util.Queue實現至多提供了相同的元素一次

例如,這樣的specialQueue的行爲應該像這樣:

E e1; 
E e2; 
E e3; 
//... 
assertThat(e1, is(e2)); 
assertThat(e1, is(not(e3))); 

Queue<E> specialQueue; 
//... 
specialQueue.offer(e1); 
specialQueue.offer(e2); 
specialQueue.offer(e3); 


assertThat(specialQueue.poll(), is(e1)); 
assertThat(specialQueue.poll(), is(e3)); 
assertThat(specialQueue.poll(), is(null)); 
// FIFO semantics are not relevant to the question 

specialQueue.offer(e3) 
assertThat(specialQueue.poll(), is(null)); 

我想出了管理內部Set<E> alreadySeenElements的實現,守衛免受針對該組檢查將元素添加到一個委託隊列。我想知道是否已經存在「經過測試」的實施。

+3

看看這裏http://stackoverflow.com/questions/2319086/a-queue-that-ensure-uniqueness-of-the-elements – Sneh

+1

@Sneh,謝謝你讓我意識到另一個問題,它的確非常接近我的。那裏的答案似乎更多地關注隊列中元素輸入期間元素的唯一性,而不是隊列生命週期中元素的唯一性。 – Abdull

+1

我認爲唯一性要求是打破隊列合同。例如。如果由於容量限制而無法添加元素,Queue.add必須返回true或拋出IllegalStateException。 –

回答

0

就像評論者所建議的那樣,您比Queue更能描述一種特殊的Set。據我瞭解,你的要求是:

  • 插入順序迭代
  • 集合中的每個元素是唯一的(不等於)
  • 以前看過元素可以永遠重新添加

前兩個要求是由LinkedHashSet,如this question建議。最後一項要求比較陌生,並且需要某種先前看到的值的內部存儲。例如:

public class SeenOnceLinkedHashSet<E> implements Set<E> { 
    private LinkedHashSet<E> data; 
    private HashSet<E> seen; 

    public boolean add(E e) { 
    boolean newValue = seen.add(e); 
    if (newValue) { 
     return data.add(e); 
    } 

    // and so on in other methods 
} 

請注意,該類具有無限內部內存。你可以很容易地導致使用這個類的內存不足問題,其他Set可以毫無問題地處理。如果你需要一些「曾經被添加過」的概念,這是不可避免的。你可以使用更優雅的東西,比如BloomFilter,但那會引入誤報。

就我個人而言,我會重新審視您的要求。任何類型的無界空間數據結構幾乎都是代碼味道。例如,你可以使用一個包裝類來提供.equals()更有幫助的定義嗎?或者在施工對象施工時增加額外的安全檢查,這樣不好的物體就不會建造在第一位?

相關問題