Software-Entwurfsmuster

Filteriterator

 aufwärts

Oft kommt es vor, dass beim Durchlaufen einer Folge mit einem Iterator nur diejenigen Elemente zurück­gegeben werden sollen, die einer bestimmten Bedingung genügen. Die anderen Elemente sollen übersprungen werden sollen. Zum Beispiel soll eine ArrayList durchlaufen werden, wobei aber Einträge mit dem Wert null übersprungen werden.

Ein solcher Iterator ist ein Filter­iterator. Ein Filter­iterator benutzt einen Basis­iterator (im Beispiel den normalen ArrayList-Iterator) und eine Filter­funktion, die dafür sorgt, dass nur die gewünschten Elemente zurück­gegeben werden (im Beispiel also nur diejenigen Elemente, die nicht null sind).

Der Filter­iterator ist nach dem Bridge-Entwurfs­muster gebildet. Er verwendet ein Behavior, das den Basis­iterator und die Filter­funktion enthält sowie auch gleich noch eine Factory-Methode, um den so gebildeten Iterator zu erzeugen (Bild 1). Dieses Entwurfs­muster wird auch bei der Konstruktion eines Compound-Iterators verwendet.

Bild 1: Klassendiagramm eines Filteriterators mit dem konkreten Behavior NotNullElements
Bild 1: Klassendiagramm eines Filteriterators mit dem konkreten Behavior NotNullElements

Nur die blau dargestellte Klasse NotNullElements ist vom Anwender zu schreiben (siehe nächster Abschnitt). Hierzu ist lediglich ein Basis­iterator (hier der Standard-Iterator von ArrayList) anzugeben und eine Filter­funktion zu implementieren.

Die folgenden Programm­beispiele verwenden Typ-Parameter. Die benötigten Import-Anweisungen für Iterator und ArrayList sind der Kürze halber weggelassen.

Behavior NotNullElements

Ein Behavior, das einen Filter­iterator erzeugt, wird von der abstrakten Klasse FilterIteratorBehavior abgeleitet. Diese sorgt dafür, dass ein Basis­iterator und eine Filter­funktion vorhanden sind und stellt die Factory-Methode iterator zur Verfügung.

Auf Grundlage dieser abstrakten Klasse ist das Behavior NotNullElements gebildet. Es erzeugt einen Filter­iterator, der eine ArrayList durchläuft und dabei null-Einträge überspringt. Im Konstruktor wird der Klasse die zu durch­laufende ArrayList übergeben. Dann werden die abstrakten Methoden der Basisklasse implementiert – die Methode baseIterator gibt den Basis­iterator an und die Methode pass stellt die Filter­funktion dar.

Der Typ der ArrayList-Einträge wird zunächst durch den formalen Typ-Parameter Type dargestellt.

public class NotNullElements<Type> extends FilterIteratorBehavior<Type>
{
    private ArrayList<Type> a;

    public NotNullElements(ArrayList<Type> a_)
    {
        a=a_;
    }

    // base iterator
    @Override
    public Iterator<Type> baseIterator()
    {
        return a.iterator();    // standard iterator of ArrayList
    }

    // filter function
    @Override
    public boolean pass(Type o)
    {
        return o!=null;
    }

}

Anwendung

Die folgende Main-Funktion in der Klasse TestNotNullElements testet den Filter­iterator. Sie gibt nur die Einträge "1", "2" und "3" aus.

public class TestNotNullElements
{
    public static void main(String[] args)
    {
        ArrayList<String> a=new ArrayList<String>();
        a.add(null);
        a.add("1");
        a.add(null);
        a.add("2");
        a.add(null);
        a.add(null);
        a.add("3");
        a.add(null);
 
        Iterator<String> it=new NotNullElements<String>(a).iterator();
        while (it.hasNext())
            System.out.println(it.next());
    }
}

 

Es gibt auch die Möglichkeit, eine eigene Klasse NotNullIterator vorzusehen. Damit wird aus dem obigen Aufruf new NotNullElements<String>(a).iterator() mit der Factory-Methode iterator der einfachere Aufruf new NotNullIterator<String>(a).

Die ent­sprechende Klasse NotNullIterator ist wie folgt implementiert.

// eigener Iterator statt Factory-Methode iterator
public class NotNullIterator<Type> extends FilterIterator<Type>
{
    public NotNullIterator(ArrayList<Type> a)
    {
        super(new NotNullElements<Type>(a));
    }
}

 

Wenn es nur um Listen mit dem Datentyp String geht, lässt sich der Aufruf eines Iterators noch weiter zu new NotUndefStrIterator(a) vereinfachen, unter Verwendung der folgenden Klasse.

// eigener Iterator für Strings
public class NotUndefStrIterator extends FilterIterator<String>
{
    public NotUndefStrIterator(ArrayList<String> a)
    {
        super(new NotNullElements<String>(a));
    }
}

 

Zusammenfassung

Die konkret benötigte Funktionalität eines Filter­iterators wird in einem Behavior (hier NotNullElements) festgelegt. Dies geschieht durch Angabe eines Basis­iterators und einer Filter­funktion.

Zugrunde­gelegt werden dabei getestete Implementierungen der Klassen FilterIterator und FilterIteratorBehavior. Diese finden sich auch im Java-Archiv de.fh-flensburg.inf.lang.iterators.jar.

 

Weiter mit:  [Compound-Iterator]   [Implementierung FilterIterator]   oder   up

 

homeH.W. Lang   Hochschule Flensburg   lang@hs-flensburg.de   Impressum   ©   Created: 05.02.2008   Updated: 03.03.2017
Valid HTML 4.01 Transitional

Hochschule Flensburg
Campus Flensburg

Informatik in Flensburg studieren...

 

Neu gestaltetes Studienangebot:

Bachelor-Studiengang
Angewandte Informatik

mit Schwerpunkten auf den Themen Software, Web, Mobile, Security und Usability.

Ihr Abschluss
nach 7 Semestern:
Bachelor of Science

 

Ebenfalls ganz neu:

Master-Studiengang
Angewandte Informatik

Ein projektorientiertes Studium auf höchstem Niveau mit den Schwerpunkten Internet-Sicherheit, Mobile Computing und Human-Computer Interaction.

Ihr Abschluss
nach 3 Semestern:
Master of Science

 

Weitere Informatik-Studienangebote an der Hochschule Flensburg:

Medieninformatik

Wirtschaftsinformatik