代码之家  ›  专栏  ›  技术社区  ›  Aaron Digulla

需要延迟和地图的混合

  •  2
  • Aaron Digulla  · 技术社区  · 14 年前

    我有一个没有保存按钮的应用程序;保存是在后台自动进行的。当用户使用应用程序时,任务被创建并放入队列中执行。其中一些是延迟的,例如,当您开始键入时,我会等待200毫秒,然后才更新数据库中的相应值。

    为了使代码更易于使用,我希望能够向队列中添加一个带有延迟和“键”的任务。如果已经有一个任务具有相同的“键”,那么应该忽略我的第二个任务(因为相同的操作已经排队)。

    这样的事情已经存在了吗?

    3 回复  |  直到 14 年前
        1
  •  3
  •   Jeroen Rosenberg    14 年前

    TreeMap 班级。使用可以传递比较器的构造函数。通过这种方式,可以让映射按延迟排序(因为此类实现了可比较的接口)。在将“任务”添加到映射之前,请使用containsKey方法检查密钥是否已经存在。

        2
  •  1
  •   Andreas Dolk    14 年前

    我就是这样理解这个问题并接受挑战的:

    public TaskWrapper<T> {
       private T task;
       private long delayInMillis;
       private long key;
    
       public TaskWrapper(T task, long delayInMillis, long key) {
         this.task = task;
         this.delayInMillis = delayInMillis;
         this.key = key;
       }
    
       // getter, setters, and so on
    
       public boolean equals(Object o) {
          if (o == null || !(o instanceof TaskWrapper)) return false;
          return key == ((TaskWrapper) o).key;
       }
    }
    

    队列装饰器添加类似“set”的行为。队列没有“contains”方法,因此我需要一个额外的集合来记录实际请求的对象。将实现所有更改队列的方法,以保持内部队列和集合之间的一致性。这个快速草稿不是线程安全的,只显示 add

    public SetQueue<TaskWrapper> implements Queue<T> {
      private Queue<TaskWrapper> queue;
      private Set<TaskWrapper> set = new HashSet<TaskWrapper>();
    
      public SetQueue(Queue<TaskWrapper> queue) {
        this.queue = queue;
      }
    
      // just to demonstrate the idea
      public boolean add(TaskWrapper<?> task) {
         if (set.contains(task) 
            return false;
         boolean result = queue.add(task);
         if (result) 
            set.add(task);
         return result;
      }
    

    (可能满是bug,我手头没有IDE。只是草稿)

        3
  •  0
  •   Ovidiu Lupas    14 年前

    我想到的一个优雅的解决方案是:使用具有 priority blocking queue