Kleine Java Tips: Einfach über eine Map iterieren

Ist man von früher gewohnt über das KeySet zu iterieren um alle Elemente einer Map aufzurufen, wird hier ein neuer Weg über das EntrySet und foreach gezeigt.

Hat man eine Map und muss nicht nur mit einem Element sondern mit allen Elementen die die Map beinhaltet weiterarbeiten, ist ein gebräuchlicher Weg über den KeySet der Map zu iterieren

for (Iterator it = map.keySet().iterator(); it.hasNext(); ){
    Object key = it.next();
    Object vlaue = map.get(key);
}

Seit Java 1.5, und damit eigentlich schon recht lange, gibt es jedoch einen bequemeren Weg. Die foreach Schleife in Java funktioniert mit allen Objekten die Iterable implementieren, und somit auch mit dem EntrySet einer Map.

for (Entry e : map.entrySet()){
    e.getKey();
    e.getValue();
}

So bekommt man zu einem viel übersichlicherem Code, der obendrein noch äußerst geschmeidig wirkt :D

Ganz hilfreich ist dabei der im TryCatchFinally Blog veröffentlcihte Artikel, der Zeigt wie man dafür ein schnell zu verwendendes Template in Eclipse anlegt:

http://blubberbart.blogspot.com/2011/04/eclipse-code-template-uber-eine-map.html

Happy Coding!

Ähnliche Artikel:

Java: Element aus List entfernen mit einer Schleife

In Java läuft man beim Entfernen eines Elementes aus Listen mit einer Schleife Gefahr die Integrität dieser zu torpedieren. Lesen Sie wie man dies verhindert.

Auf folgende Problemstellung stößt man doch immer wieder: Man muss ein Element aus einer Liste entfernen, welches bestimmten Kriterien entspricht. Jedoch kann man beim Löschen von Elementen aus einer Liste schnell in eine Falle tappen, indem man mit einfachen Schleifenkonstruktionen die Threadsicherheit aufs Spiel setzt. Wie möchte ich in folgenden Sourcen aufzeigen:

Es bietet sich, um die Elemente einer Liste zu überprüfen, die erweiterte for Schleife an. Sie ist gut zu lesen, einfach zu programmieren, man bekommt jedes einzelne Element als Referenz und muss nicht selbst auf den Index achten.

for (Element e : liste){
	if (e.read().equals(“ja”) { ... };
}

Nutzt man dieses Konstrukt um ein Element der Liste ausfindig zu machen, unterwandert man beim Löschen die Integrität des Listen-Objekts und Java wirft eine ConcurrentModificationException. Dabei ist noch nichtmals mehr als ein Thread notwendig, wie im folgenden Beispiel gezeigt. Der Aufruf erscheint wie von einem anderen Thread. Das Element wird zwar gelöscht, jedoch beim Versuch auf das nächste Element zu wechseln tritt  ein Fehler auf und das zweite Objekt das den Kriterien entsprochen hat wird nicht mehr aus der Liste entfernt.

import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.List;

public class RemoveFromListTest {

	private List test = new ArrayList();

	private void init() {
		test.add("start");
		test.add("in");
		test.add("the");
		test.add("middel");
		test.add("of");
		test.add("the");
		test.add("array");
		test.add("end");
	}

	private void printArray() {
		System.out.println(test);
	}

	private void remove(Object toRemove) {
		try {
			for (String a : test) {
				if (a.equals(toRemove)) {
					test.remove(a);
				}
			}
		} catch (ConcurrentModificationException e) {
			System.out.println("Exception when deleting \""
					+ toRemove.toString() + "\"");
		}
	}

	public static void main(String[] args) {
		RemoveFromListTest testList = new RemoveFromListTest();
		testList.init();
		testList.printArray();
		testList.remove("in");
		testList.printArray();
		testList.remove("start");
		testList.printArray();
		testList.remove("end");
		testList.printArray();

	}
}

Die Ausgabe:

[start, in, in, the, middel, of, the, array, end]
Exception when deleting „in“
[start, in, the, middel, of, the, array, end]
Exception when deleting „start“
[in, the, middel, of, the, array, end]
Exception when deleting „end“
[in, the, middel, of, the, array]

Erste Intention das zu Lösen ist es vielleicht sich die zu löschenden Objekte zu merken und später nach der Schleife aus der Liste zu nehmen. Die saubere Lösung für diese Fehlerquelle ist jedoch ein Iterator. Mit ihm können wir das Element direkt zum Zeitpunkt des Auffindens entfernen.

for (Iterator iterator = this.test.iterator(); iterator.hasNext();) {
	String a = iterator.next();
	if (a.equals(toRemove)) {
		iterator.remove();
	}
}

Somit läuft man nicht mehr offen in eine Exception und muss sich die zu löschenden Objekte auch nirgends extra merken, was zu übersichtlicherem Code führt.

Na denn, schaut nach wie ihr sowas schon in alten Projekten gelöst habt! Könnt es auch gerne unten in die Kommentare stellen.

Greets!

Mehr Informationen

zum Iterator im Galileo Computing Open Book: Java ist auch eine Insel

Die ConcurrentModificationException beschrieben in der Java API

Ähnliche Artikel: