单击鼠标时向集合添加元素

时间:2016-03-27 20:52:03

标签: java collections concurrency

我在这个网站上看到很多关于这个问题的问题,但不是这个问题,所以无论如何我都会问。如果这是重复的话,请道歉。

我有一个包含Points的HashSet,它们显示在一个窗口中。由于Points一直在移动,我需要总是迭代我的HashSet以更新窗口。总而言之,我的主循环看起来像这样:

HashSet<Point> h = ...
while(true){
  for(Point p : h){
    p.update();
    draw(p);
  }
}

现在这里是事情向南的地方。我想,当用户点击屏幕上的某个位置时,会在此处添加一个Point。但是,在事件处理程序中直接向HashSet添加元素的天真方法会失败,因为在迭代时无法对其进行修改。天真方法的基本代码:

public void mouseClicked(MouseEvent e){
  h.add(new Point(e.getX, e.getY));
}

我为避免这种行为而想到的一个想法是维护一个临时List,其中要保留要添加的点,等待HashSet的主迭代完成以添加新点。但这对我来说似乎并不安全,因为(不幸的)用户可以设法在迭代List时添加一个

那么这里的最佳实践解决方案是什么?

2 个答案:

答案 0 :(得分:1)

这是Swing和Swing是单线程的,所以这不是问题。简单

  • 摆脱while (true)循环,
  • 不要试图反复迭代,因为这会导致灾难。
  • 使用Swing Timer代替迭代之间的合理延迟
  • 现在线程不会成为一个问题,因为在迭代过程中你无法将一个Point添加到列表中。

答案 1 :(得分:0)

我可能有两个相同的HashSet,并将值添加到您当前没有迭代的那个。通过简单地使用布尔值来迭代哪一个。

一些伪代码将是:

HashSet h1 = [...]
HashSet h2 = [...]
boolean b = true;

[...]

if(b) {
    iterateOver(h1);
    h1 = h2;
    b = !b;
} else {
    iterateOver(h2);
    h2 = h1;
    b = !b;
}

[...]

if(b) {
    h2.add();

} else {
    h1.add();
}

[...]