java.util.Queue实现,最多提供一次相同的元素

时间:2015-07-03 23:16:00

标签: java

我正在寻找一个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的实现,并通过检查该集合来防止向委托队列添加元素。我想知道是否已经存在一个经过战斗考验的&#34;实施

1 个答案:

答案 0 :(得分:0)

与评论者的建议一样,您更多地描述了一种特殊的Set而不是Queue。据我所知,您的要求是:

  • 插入顺序迭代
  • 集合中的每个元素都是唯一的(不相等)
  • 之前看到的元素永远不会重新添加

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()更有用的定义?或者在对象构造时添加额外的安全检查,以便首先不构建不良对象?