当前位置: 首页 > 面试题库 >

用Java实现去抖动

龚远
2023-03-14
问题内容

对于我正在编写的某些代码,我可以使用debounceJava中的一个不错的通用实现。

public interface Callback {
  public void call(Object arg);
}

class Debouncer implements Callback {
    public Debouncer(Callback c, int interval) { ... }

    public void call(Object arg) { 
        // should forward calls with the same arguments to the callback c
        // but batch multiple calls inside `interval` to a single one
    }
}

call()被称为多次interval毫秒具有相同参数的回调函数应调用一次。

可视化:

Debouncer#call  xxx   x xxxxxxx        xxxxxxxxxxxxxxx
Callback#call      x           x                      x  (interval is 2)
  • (某种程度上)这已经在某些Java标准库中存在了吗?
  • 您将如何实施?

问题答案:

请考虑以下线程安全解决方案。请注意,锁定粒度是在密钥级别上的,因此仅同一密钥上的调用会相互阻塞。它还处理在调用call(K)时发生的密钥K过期的情况。

public class Debouncer <T> {
  private final ScheduledExecutorService sched = Executors.newScheduledThreadPool(1);
  private final ConcurrentHashMap<T, TimerTask> delayedMap = new ConcurrentHashMap<T, TimerTask>();
  private final Callback<T> callback;
  private final int interval;

  public Debouncer(Callback<T> c, int interval) { 
    this.callback = c;
    this.interval = interval;
  }

  public void call(T key) {
    TimerTask task = new TimerTask(key);

    TimerTask prev;
    do {
      prev = delayedMap.putIfAbsent(key, task);
      if (prev == null)
        sched.schedule(task, interval, TimeUnit.MILLISECONDS);
    } while (prev != null && !prev.extend()); // Exit only if new task was added to map, or existing task was extended successfully
  }

  public void terminate() {
    sched.shutdownNow();
  }

  // The task that wakes up when the wait time elapses
  private class TimerTask implements Runnable {
    private final T key;
    private long dueTime;    
    private final Object lock = new Object();

    public TimerTask(T key) {        
      this.key = key;
      extend();
    }

    public boolean extend() {
      synchronized (lock) {
        if (dueTime < 0) // Task has been shutdown
          return false;
        dueTime = System.currentTimeMillis() + interval;
        return true;
      }
    }

    public void run() {
      synchronized (lock) {
        long remaining = dueTime - System.currentTimeMillis();
        if (remaining > 0) { // Re-schedule task
          sched.schedule(this, remaining, TimeUnit.MILLISECONDS);
        } else { // Mark as terminated and invoke callback
          dueTime = -1;
          try {
            callback.call(key);
          } finally {
            delayedMap.remove(key);
          }
        }
      }
    }  
  }


 类似资料:
  • 问题 你想只执行某个函数一次,在开始或结束时把多个连续的调用合并成一个简单的操作。 解决方案 使用一个命名函数: debounce: (func, threshold, execAsap) -> timeout = null (args...) -> obj = this delayed = -> func.apply(obj, args) unless exe

  • 本文向大家介绍angular.js和vue.js中实现函数去抖示例(debounce),包括了angular.js和vue.js中实现函数去抖示例(debounce)的使用技巧和注意事项,需要的朋友参考一下 问题描述 搜索输入框中,只当用户停止输入后,才进行后续的操作,比如发起Http请求等。 学过电子电路的同学应该知道按键防抖。原理是一样的:就是说当调用动作n毫秒后,才会执行该动作,若在这n毫秒

  • 问题内容: 在AngularJS中,我可以通过使用ng-model选项来反跳模型。 如何在Angular中对模型进行反跳?我试图在文档中搜索反跳,但找不到任何东西。 一种解决方案是编写我自己的防抖动功​​能,例如: 和我的HTML 但是我正在寻找一个内置函数,Angular中有一个吗? 问题答案: 针对RC.5更新 使用Angular 2,我们可以在窗体控件的可观察对象上使用RxJS运算符进行反跳

  • 这是我现在的效果,拖动时会抖动,并且点击图例后都会执行一次这个动画: 下面复现代码的gif图: echarts 编辑器 如何给这个动画去抖呢? 其次: 有更好的动画效果推荐吗? 点击图例后都会执行一次这个动画,这个怎么修改呢?

  • 本文向大家介绍jQuery实现网页抖动的菜单抖动效果,包括了jQuery实现网页抖动的菜单抖动效果的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jQuery实现网页抖动的菜单抖动效果。分享给大家供大家参考。具体如下: 这里的jQuery抖动导航菜单效果,兼容IE7/8/9及其它主流浏览器,使用方法:先引入jQuery脚本库和jquery.shake.js文件,然后在需要的元素上调用sha

  • 本文向大家介绍C语言实现窗口抖动,包括了C语言实现窗口抖动的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言窗口抖动的具体实现代码,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。