# Fragen zu Arrays?



## bruce85 (10. Dez 2013)

Hallo,
wie könnte ich ein eigene Array Liste erstellen, um später einzelne Elemente zu löschen bzw. hinzuzufügen?

Ich habe mir das so vorgestellt:

```
ArrayList<Feld> feld = new ArrayList<Feld>();
public class Feld {
	int typ;
	int frames;
	double posX;
	double posY;
}
```

leider weiss ich nicht, ob das hier so funktioniert.

Wie könnte man ein Array erstellen, um neue Elemente mit add hinzuzufügen und später bestimmte Elemente wieder zu löschen?

Ich bedanke mich schonmal im Voraus.

MfG


----------



## VfL_Freak (10. Dez 2013)

Moin,



bruce85 hat gesagt.:


> leider weiss ich nicht, ob das hier so funktioniert.


Hast Du es dennmal ausprobiert?
Was klappt denn nicht?
Poste ggf. die konkreten Aufrufe und die dann auftretenden Fehlermeldungen !

Gruß
Klaus


----------



## bruce85 (10. Dez 2013)

Achso, Sry.

Ich konnte es noch nicht ausprobieren, da ich nicht weiss, wie ich ein Element mit meine Eigenschaften hinzufügen kann, diese sich im Feld Klasse befinden mit ArrayList.

Wie kann ich mit ArrayList ein Element hinzufügen, mit meine Eigenschaften, diese sich in der Klasse Feld befinden?

*Edit:* Ich hab das so versucht:

```
Feld mFeld = new Feld();
mFeld.typ = 3;
feld.add(mFeld);

for (int i=0; i<feld.size(); i++) {

}
```
nur, wie lese ich dann diese Elemente wieder aus?

*Edit:* Ich hab es hinbekommen:

```
for (int i=0; i<feld.size(); i++) {
	System.out.println(""+feld.get(i).typ);
}
```

Trotzdem danke für die antwort.

MfG


----------



## kurztipp (11. Dez 2013)

Hallo,





bruce85 hat gesagt.:


> *Edit:* Ich hab es hinbekommen:
> 
> ```
> for (int i=0; i<feld.size(); i++) {
> ...


wenn Du schon List nimmst und das Iterable ist, wieso dann nicht: 
	
	
	
	





```
for (Object object : objects) {
                //do something
            }
```
Ist IMHO bequemer 

Gruß


----------



## bruce85 (11. Dez 2013)

Vielen Dank, ist natürlich bequemer und funktioniert auch.

Nur wenn ich ein Element entfernen möchte, dann erhalte ich eine fehlermeldung:

```
12-11 07:33:53.098: E/AndroidRuntime(1183): java.util.ConcurrentModificationException
12-11 07:33:53.098: E/AndroidRuntime(1183): 	at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
```

Hier ein beispiel von mir:

```
for (Feld f : feld) {
    	if (f.moveFeldDownAnz == 0) {
    		map[mapNr-1].spielfeld[f.feldX][f.feldY].frames = f.frames;
    		map[mapNr-1].spielfeld[f.feldX][f.feldY].typ = f.typ;
    		feld.remove(f);
    	}
}
```

wenn ich unter feld.remove(f) break; hinzufüge, dann klappt das, aber es sollte ja auch so funktionieren, ohne die Schleife abzubrechen.

Woran könnte das denn liegen?

MfG


----------



## kurztipp (11. Dez 2013)

Hallo,

die API sagt: 





> This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
> For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it.


Ich geh mal davon aus, dass Du hier ein Spiel programmieren willst und dass Du daher (unbewusst) Threads benutzt. Also liegt es nahe, dass der Fehler wegen der Benutzung der Threads geworfen wird, wie schon die API verlauten lässt.

Ich denke google wird da schnell brauchbare Lösungsansätze liefern:
Scheinbar verträgt sich der Iterator nicht mit remove.

Gruß


----------



## bruce85 (12. Dez 2013)

Danke Dir.
Ich hab das jetzt so gelöst:


```
for(Iterator<Block> it = block.iterator(); it.hasNext();) {
    Block b = it.next();

    if (b.moveFeldDownAnz == 0) {
    	map[mapNr-1].spielfeld[b.feldX][b.feldY].frames = b.frames;
    	map[mapNr-1].spielfeld[b.feldX][b.feldY].typ = b.typ;
    	it.remove();
    }
}
```

Nun funktioniert es, aber diese Methode scheint ziemlich langsam zu sein, macht es sinn, in dieser Schleife Bewegungen von Bilder durchzuführen?

*Edit:* Es hat sich erledigt, funktioniert doch, wie es sein soll.

Vielen Dank für die Hilfe.

MfG


----------



## bruce85 (13. Dez 2013)

Hallo nochmal,
ich erhalte ab und zu trotzdem diese fehlermeldung:

```
12-13 14:59:45.282: E/AndroidRuntime(29917): 	at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
```

Dieser fehler zeigt mir an dieser stelle an:

```
for(Iterator<SpielfeldData> it = spielfeldData.iterator(); it.hasNext();) {
    SpielfeldData sData = it.next();
    ..............
}
```

Kann es Vielleicht daran liegen, dass ich im Quellcode etwas weiter unten, bestimmte Elemente entferne?

```
int id = spielfeldData.get(spielfeldData.size()-1).id;  	            						
for(Iterator<SpielfeldData> it = spielfeldData.iterator(); it.hasNext();) {
    SpielfeldData sData = it.next();
        if (sData.id == id) {
            it.remove();
        }
}
```

Java macht mir nur Probleme, wenn es um Array geht, das kenne ich bei anderen Programmiersprachen garnicht.

Im Spiel benutze ich eine GameLoopThread und diese Starte ich mit:

```
theGameLoopThread = new GameLoopThread(this);
		
		surfaceHolder = getHolder();
		surfaceHolder.addCallback(new SurfaceHolder.Callback() {

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

                    }
                }

            }

            public void surfaceCreated(SurfaceHolder holder) {
                theGameLoopThread.setRunning(true);
                theGameLoopThread.start();
                
                Canvas c = null;
                try {
                	c = holder.lockCanvas(null);
                	synchronized (holder) {
                		onDraw(c);
                	}
                } finally {
                // do this in a finally so that if an exception is thrown
                // during the above, we don't leave the Surface in an
                // inconsistent state
                	if (c != null) {
                		holder.unlockCanvasAndPost(c);
                	}
                }
            }

			public void surfaceChanged(SurfaceHolder holder, int format,
					int width, int height) {
			}
		});
```

Hier ist die GameLoopThread Klasse:

```
public class GameLoopThread extends Thread {
    private GameView theView;
    private boolean isRunning = false;
 
    public GameLoopThread(GameView theView) {
        this.theView = theView;
    }
 
    public void setRunning(boolean run) {
        isRunning = run;
    }
 
    @Override
    public void run() {
        while (isRunning) {
            Canvas theCanvas = null;
            //startTime = System.currentTimeMillis();
            try {
                theCanvas = theView.getHolder().lockCanvas();
                synchronized (theView.getHolder()) {
                    theView.onDraw(theCanvas);
                }
            } finally {
                if (theCanvas != null) {
                    theView.getHolder().unlockCanvasAndPost(theCanvas);
                }
            }
        }
    }
 
}
```

Kann es Vielleicht auch am GameLoopThread liegen?
Wenn ja, gibt es Vielleicht eine bessere Methode, den Canvas immer wieder neu zu zeichnen und onDraw aufzurufen?

Danke schonmal.

MfG


----------



## knilch (14. Dez 2013)

Hi,
Die Exception sagt aus, dass du während dem iterieren der ArrayList versucht hast, ein Element zu entfernen.

Du kannst es so machen, dass du eine neue ArrayList  erstellst und dann alle gewünschten Elemente in dieser List hinzufügst. Dann wird am Schluss noch die Referenz geändert.

```
ArrayList<SpielfeldData> temp = new ArrayList<SpielfeldData>();
   
int id = spielfeldData.get(spielfeldData.size()-1).id;    

for(SpielfeldData sData : spielfeldData) {
   if (sData.id != id) {
       temp.add(sData ); // so werden alle Elemente deren id != id ist, hinzugefügt.
	}
}

spielfeldData = temp;
 
// Am Schluss wird die Referenz von temp an spielfeldData zuweisen.
// Nun hast du eine List, in derdas Element mit id entfernt wurde.
```


----------



## bruce85 (14. Dez 2013)

Ich Danke Dir.

Das Problem lag wohl daran, das ich die Komplette ListArray gelöscht hatte:

```
@Override
public boolean onTouchEvent(MotionEvent e) {
    if(e.getAction() == MotionEvent.ACTION_UP) {
        spielfeldData.clear();
    }
    return true;
}
```

jetzt hab ich es so gemacht:

```
@Override
public boolean onTouchEvent(MotionEvent e) {
    if(e.getAction() == MotionEvent.ACTION_UP) {
        for(Iterator<SpielfeldData> it = spielfeldData.iterator(); it.hasNext();) {
            SpielfeldData sData = it.next();
            sData.delete = true;
        }
    return true;
}
```

Die Daten lösche ich dann dort, wo die Daten gezeichnet werden mit:

```
if (sData.delete) {
	it.remove();
}
```

Bis jetzt klappt es ohne Probleme, ich Danke Dir trotzdem für die Hilfe.

MfG


----------

