首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >迭代Hashmap导致崩溃

迭代Hashmap导致崩溃
EN

Stack Overflow用户
提问于 2015-02-25 00:16:31
回答 1查看 391关注 0票数 1

我注意到我的应用程序最近崩溃了很多,在调试之后,我发现当我迭代hashmap时,一些随机崩溃了。

我像这样迭代了它们:

代码语言:javascript
复制
for (Map.Entry<Point, Particle> entry : spawned.entrySet()) {
                entry.getValue().Draw(canvas);
        } 

这导致了:

之后,我尝试用迭代器遍历它们,如下所示:

代码语言:javascript
复制
        Iterator<Map.Entry<Point, Particle>> entries = spawned.entrySet().iterator();
    while (entries.hasNext()) {
        Map.Entry<Point, Particle> entry = entries.next();
        entry.getValue().Draw(canvas);
    }

但这导致了:

如果任何人怀疑它必须对它做些什么,这里是在粒子类中:

代码语言:javascript
复制
public class Particle {
    Bitmap bit;
    int alpha = 0;
    boolean appeared = false;
    boolean dissapiread = false;
    int time = 1;
    PointF position;
    Handler handler;
    int counter = 0;
    PointF newpose;
    float newsize=0;
    int timer2=0;
    public Particle(Bitmap b, PointF p, int time) {
        int rand=(randInt(-b.getWidth()/2, b.getWidth()));
        this.bit = Bitmap.createScaledBitmap(b, b.getWidth()+rand,b.getHeight()+rand,false);
        this.position = p;
        this.time = time;
        newpose= new PointF();
        newpose.x=p.x+randInt(-15000, 15000);
        newpose.y=p.y+randInt(-15000,15000);

    }

    public void Draw(Canvas c) {
        update();
        Paint paintAlpha = new Paint();
        paintAlpha.setAlpha(alpha);
        c.drawBitmap(bit, position.x, position.y, paintAlpha);
    }
    public static int randInt(int min, int max) {
        Random rand = new Random();
        int randomNum = rand.nextInt((max - min) + 1) + min;
        return randomNum;
    }
    private void update() {
        if(position.x<newpose.x){
            position.x+=0.10f;
        }
         if(position.x>newpose.x){
            position.x-=0.10f;
        }
        if(position.y<newpose.y){
            position.y+=0.10f;
        }
         if(position.y>newpose.y){
            position.y-=0.10f;
        }
         if(dissapiread==false){
         if(timer2==0){
             newsize+=0.10;
             try {
                 bit=Bitmap.createScaledBitmap(bit, bit.getWidth()-(int)newsize,bit.getHeight()-(int)newsize,false);
            } catch (Exception e) {
                // TODO: handle exception
            }
         timer2=5;
         }
         else
             timer2--;
         }

        if (appeared == false) {
            if (alpha <=240) {
                alpha =alpha+10;
            } 
            else {
                if(counter==0){

                counter=time;
                }
                if(counter==1){
                    appeared=true;
                }
                else
                    counter--;
            }
        } else {
            if (dissapiread == false) {
                if (alpha != 0) {
                    alpha=alpha-10;
                }
                else
                    dissapiread = true;
            }
        }
    }
}

请注意,我知道在我当前的代码中,我不需要使用hashmap,我只想知道为什么它会崩溃,因为它也发生在其他地方。

编辑:完整代码:

代码语言:javascript
复制
public class gameview extends SurfaceView {

    private GameLoopThread gameLoopThread;
    private SurfaceHolder holder;
    Bitmap partic;
    Particle pp;
    Map<Point, Particle> spawned = new HashMap<Point, Particle>();
public gameview(Context c) {
    super(c);
    partic=BitmapFactory.decodeResource(getResources(),
            R.drawable.particle_fire);
     pp=new Particle(partic, new PointF(0,0), 100);
    gameLoopThread = new GameLoopThread(this);
    this.requestFocus();
    this.setFocusableInTouchMode(true);
    holder = getHolder();
    holder.addCallback(new SurfaceHolder.Callback() {

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            boolean retry = true;
            gameLoopThread.setRunning(false);
            while (retry) {
                try {
                    gameLoopThread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            gameLoopThread.setRunning(true);
            gameLoopThread.start();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format,
                int width, int height) {
        }
    });
}
@Override
public void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    canvas.drawColor(Color.BLACK);
    pp.Draw(canvas);
        Iterator<Map.Entry<Point, Particle>> entries = spawned.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<Point, Particle> entry = entries.next();
            entry.getValue().Draw(canvas);
        }
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = (float) (event.getX());
    float y = (float) (event.getY());
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        spawned.put(new Point((int)x,(int)y), new Particle(partic, new PointF(x,y), 100));
        break;
    }
    return super.onTouchEvent(event);
}
private void newParticle(int x,int y){

    spawned.put(new Point(0,0), new Particle(partic, new PointF(x,y), 100));
}

}
EN

回答 1

Stack Overflow用户

发布于 2015-02-25 00:24:50

在其Draw方法中更新Partice。这导致了你在循环中体验到的ConcurrentModificationException

如果要避免此类异常,可以创建粒子集合的克隆,在该克隆上迭代和修改原始数据。然而,对于您需要做的事情来说,克隆可能相当麻烦。

通过克隆,我的意思是将HashMap的密钥复制到一个新的集合中,并对该集合进行迭代。在循环中,您可以通过遍历的键访问HashMap值。修改粒子应该没问题。请注意,如果更新更改了对象的HashValue,则需要小心。

编辑:

正如@fge指出的那样,使用CuncurrentHashMap也可以很好地解决这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28700844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档