【问题标题】:JAVA how to remove element from list 2 seconds after adding it?JAVA如何在添加元素后2秒从列表中删除元素?
【发布时间】:2021-11-01 12:49:35
【问题描述】:

我正在使用的库是处理库。我目前正在制作游戏,我需要在添加后每 2 秒从列表中删除项目(项目将由 Keypressed SPACE 添加)。我试过这个:

List<String> items = new ArrayList<>();

boolean timeStarted;

int timeDuration = 2000;
int startTime = 0;

if (timeStarted) {
            
    int currentDuration = millis() - startTime;

    if (currentDuration >= timeDuration) {

        items.remove(0);

        startTime = millis();
        timeStarted = false;
    }
}

public void keyPressed(KeyEvent e) {

    int keycode = e.getKeyCode();

    if (keycode == 32) { // SPACE
        startTime = millis();
        timeStarted = true;
        items.add("new item"); 
    }

但这只会删除列表中的第一项,如果我按 SPACE 太快(同时添加太多项)会卡住。

谁能帮助我或告诉我如何处理这个问题?提前致谢!

【问题讨论】:

  • 我认为计算元素保存时间的列表和一些变量不是实现您的想法的正确选择。我认为您应该寻找一些缓存方法。我正在考虑类似Guavacaffeine
  • @Eritrean 感谢您的评论,但我只想通过使用处理库来完成此操作,因为我不熟悉其他人...

标签: java processing


【解决方案1】:

我个人不会将线程和处理混搭在一起。

如果您正在使用处理,并且正在为游戏执行此操作(因此可能不需要毫秒精度),为什么不直接使用帧速率作为时间测量?您的处理程序总是应该以一组frameRate 运行(除非您有一些性能问题)。在动作发生的帧被绘制之前,您也不会看到任何事情发生,因此如果您的动作在帧之间完成并不重要,您的最终用户不会看到差异。

处理中的默认frameRate 是30fps。您可以使用 frameRate() 函数 (docs) 设置自定义费率。 frameCount 返回绘制的帧数(第一帧为 0)。

因此,您可以执行以下伪代码之类的操作

int removeItemCheckpoint;
int removeItemDuration;

void setup()
{
    // 30 frames per second
    frameRate(30);
    // window is two seconds, so this duration will last two times the frameRate
    removeItemDuration = frameRate * 2;
}

void draw()
{
   if (some input)
   { 
      // set checkpoint to current frame count + the duration
      removeItemCheckpoint = frameCount + removeItemDuration;
   }

   // if current frame count is larger than the checkpoint, perform action
   if (frameCount > removeItemCheckpoint)
   {
      // set checkpoint to pseudo infinity
      removeItemCheckpoint = Integer.MAX_VALUE;
      // remove item here
   }
}

如果您想一次处理多个对象,您可以创建类似已创建列表索引/检查点pairs 的列表,然后循环遍历它们。

List<Pair<int, int>> toBeRemoved = new List<Pair<int, int>>();

// add a new pair
toBeRemoved.add(new Pair(itemIndex, frameCount + removeItemDuration));

// loop over the list

foreach (Pair<int, int> item in toBeRemoved)
{
    if (frameCount > item.getKey())
    {
        itemList.remove(item.getValue());
    }
}

【讨论】:

  • 谢谢你的回答 :) 我的代码在这里配对失败(我使用的是 java 8)
  • 编辑:我想出了一个类似的方法来做到这一点!非常感谢!
  • 没问题。对的语法可能是错误的,它可能需要说 new Pair&lt;int,int&gt;(itemIndex, frameCount + removeItemDuration) 或类似的东西。
【解决方案2】:

在添加 2 秒后使用 while 来检查列表中的元素。

// remove element from list 2 seconds after adding it
while (startedTime+timeDuration >= System.currentTimeMillis()) {
    // If delete exit while
    items.remove(0);
    break;
}

当您可以按空格键时,使用线程删除您的项目。

if (keycode == 32) { // SPACE
     long startTime = System.currentTimeMillis();
     items.add("new item"); 
     // Thread execute
     Thread thread = new Thread(new Remover(startTime, items));
     thread.start();
}

@Override
public void run() {
    // remove element from list 2 seconds after adding it
    while (startedTime+timeDuration >= System.currentTimeMillis()) {
        // If delete exit while
        items.remove(0);
        break;
    }
     // whether item is deleted
    System.out.println(items);
}

完整代码

public class Main {

    public static void main(String[] args) {
        Main main = new Main();
        
        main.keyPressed(32);

    }
    
    // Integer instead of Keycode
    public void keyPressed(Integer keycode) {
        
        List<String> items = new ArrayList<String>();

        if (keycode == 32) { // SPACE
            long startTime = System.currentTimeMillis();
            items.add("new item"); 
            // Check items
            System.out.println(items);
            
            // Thread execute
            Thread thread = new Thread(new Remover(startTime, items));
            thread.start();
        }
    }
    
}

class Remover implements Runnable{
    
    List<String> items;
    
    int timeDuration = 2000;
    
    long startedTime;
    
    public Remover(long startedTime,List<String> items) {
        this.startedTime = startedTime;
        this.items = items;
    }

    @Override
    public void run() {
        // remove element from list 2 seconds after adding it
        while (startedTime+timeDuration >= System.currentTimeMillis()) {
            // If delete items,Exit while
            items.remove(0);
            break;
        }
         // whether item is deleted
        System.out.println(items);
    }
    
    
}

【讨论】:

  • 感谢您的回答。我试着把这些写成一个类(没有分开),但我不知道我可以把Thread放在哪里......另外,我对Thread感到困惑,它有什么作用?跨度>
  • @AAAAAAbc 线程可用于在后台执行复杂的任务,而不会中断主程序。当在这种情况下在后台按下空格键时,线程执行删除项目的元素。参考w3schools.com/java/java_threads.asp
猜你喜欢
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 2018-01-08
  • 1970-01-01
  • 2010-10-13
相关资源
最近更新 更多