我正在开发一个项目,该项目要求我根据用户输入的查询按姓名过滤一长串联系人列表。当我仍在过滤列表时,用户可以输入和删除字符。例如,我可能有一个包含 5000 个联系人的列表:
FirstName1 LastName1
FirstName2 LastName2
...
FirstName5000 LastName5000
用户有一个表单,他/她可以在其中输入搜索条件,并且列表应缩小以仅显示满足搜索条件的联系人。这是我遇到的问题,如果用户输入说
J
我应该过滤列表并仅显示名字或姓氏以“J”开头的联系人。但是,用户可能会输入另一个字符或删除字符,在这种情况下,我需要重新启动列表的过滤。当然,我的问题是我想以有效的方式执行此操作,而不是等到使用字母“J”完成过滤后才开始使用新标准进行过滤。有什么想法/建议吗?
最佳答案
为了避免启动太多查询(这有助于提高可扩展性),我建议实现一种机制,在启动查询之前等待给定的时间。任何时候用户在此时间范围内修改字段内容,都会中止之前的查询并安排新的查询。
类似的事情:
创建计时器并安排任务的代码:
Timer timer = new Timer();
// Schedule my task to be executed in 200 milliseconds
timer.schedule(new TimerTask() {
@Override
public void run() {
// Launch my query here
}
}, 200L);
取消先前计划任务的代码:(在用户修改某些内容时启动)
// Cancel the previous timer which will also abort the scheduled task
timer.cancel();
// Create a new timer
timer = new Timer();
// Re-schedule the task
timer.schedule(new TimerTask() {
@Override
public void run() {
// Launch my query here
}
}, 200L);
也可以使用 ScheduledExecutorService
来完成,如下所示:
创建 ScheduledExecutorService
并安排任务的代码:
// Create the ScheduledExecutorService
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
// Submit the task to be executed in 200 milliseconds
ScheduledFuture<?> future = executor.schedule(new Runnable() {
@Override
public void run() {
// Launch my query here
}
}, 200, TimeUnit.MILLISECONDS);
取消先前计划任务的代码:(在用户修改某些内容时启动)
// Cancel the task which will interrupt the thread that was executing the
// task if any
future.cancel(true);
// Re-submit the task
future = executor.schedule(new Callable<Void>() {
@Override
public Void call() throws InterruptedException {
...
// Check regularly in your code if the thread has been
// interrupted and if so throws an exception to stop
// the task immediately
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Thread interrupted");
}
...
}
}, 200, TimeUnit.MILLISECONDS);
注意:这些代码片段只是为了展示想法,并不意味着完美
关于java - Java中列表的增量过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38902632/