p. bosch
p. bosch

Reputation: 139

Working with iterators, how to use them?

I'm learning Java and I have no idea about iterators, I only worked with them in C++. The thing is, I have some classes which are 2 lists of Nodes with a value on them and I need to list them from the smallest to the biggest (1, 3, 4, 5, 5, 6.. They can be strings too but that doesn't matter). The thing is I don't know how to implement an Iterator to go through and print every Node. Here are the classes I have:

interface Conjunt<T> {
  // Descripcio general: contenidor generic sense elements repetits

  // Pre : ---
  // Post:  x  pertany al conjunt
  void afegir(T x);

  // Pre : ---
  // Post:  x  no pertany al conjunt
  void esborrar(T x);

  // Pre : ---
  // Post: diu si  x  pertany al conjunt
  boolean pertany(T x);

}

ConjuntLlista

public class ConjuntLlista<T> implements Conjunt<T> {
    // Descripcio general: conjunt implementat en forma de llista de nodes encadenats

    protected Node primer; // Primer node de la llista

    class Node {
    // Descripcio general: un node de la llista

    T valor;   // Valor dins la llista
    Node seg;  // Seguent node de la llista

    // Pre : ---
    // Post: Crea un node amb els valors dels parametres
    Node(T valor, Node seg) {
        this.valor = valor;
        this.seg = seg;
    }
    }

    class Pair {
    // Descripcio general: tupla de dos nodes   
    Node first;
    Node second;

    // Pre : ---
    // Post: Crea una tupla amb els valors dels parametres
    Pair(Node first, Node second) {
        this.first = first;
        this.second = second;
    }

    }

    // Pre : ---
    // Post: Crea un conjunt buit
    public ConjuntLlista() {
    primer = null;
    }

    // Les seguents operacions no cal especificar-les perque ja estan
    // especificades a la interface.

    public void afegir(T x) {
    if (!pertany(x)) primer = new Node(x, primer);
    }

    public void esborrar(T x) {
    Pair p = buscar(x);
    if (p.second != null) // Hem trobat  x
        if (p.first != null) //  x  no ocupa la primera posicio
        p.first.seg = p.second.seg;
        else
        primer = p.second.seg;
    }

    public boolean pertany(T x) {
    return buscar(x).second != null;
    }

    // Pre : ---
    // Post: Si el conjunt conte  x  aleshores retorna un parell  p  tal
    //       que  p.first  es el node anterior al que conte  x  i  p.second
    //       es el node que conte  x.  Si algun d'aquests nodes no
    //       existeix, es representa amb null.
    private Pair buscar(T x) {
    Node anterior = null; // Node anterior a l'actual
    Node actual = primer; // Node actual (a examinar)
    while (actual != null && !actual.valor.equals(x)) {
        anterior = actual;
        actual = actual.seg;
    }
    if (actual != null) // Hem trobat  x
        return new Pair(anterior,actual);
    else
        return new Pair(null,null);
    }

}

Here's the class where I need to add the iterator, but I don't know how to do it:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class ConjuntLlistaOrdenat1<T extends Comparable<T>>
    extends ConjuntLlista<T> 
    implements Iterable<T> {

    // Descripcio general: Conjunt que disposa d'un iterador que retorna
    //                     els elements de petit a gran.
    //
    //                     Implementacio en forma de llista ordenada,
    //                     sobreescrivint (com a minim) l'operacio afegir.

    public void afegir(T s) {
        if(this.primer != null) {
            Node q = this.primer;
            while(q.valor.compareTo(s) > 0)
                q = q.seg;
            Node p = q;
            q = new Node(s,p);
        }
    }   

}

I've looked at some examples but I couldn't understand it, can someone explain it a bit for me please?

Upvotes: 0

Views: 196

Answers (2)

fge
fge

Reputation: 121702

First of all: an iterator is a "one use" object; once an iterator has read a value, it cannot be read anymore from that iterator; once an iterator is consumed, it cannot be reused.

An iterator instance should have an internal state, so that it knows how to answer to its three methods: .hasNext(), .next(), .remove().

Here is a simple iterator implementation over an array of Strings, which does not support removal:

public class MyStringIterator
    implements Iterator<String>
{
    // What we iterate against
    private final String[] array;
    private final int size;
    // The only internal state variable
    private int currentIndex = 0;

    public MyStringIterator(final String[] array)
    {
        this.array = Arrays.copyOf(array);
        size = this.array.length;
    }

    @Override
    public boolean hasNext()
    {
        return currentIndex < size;
    }

    @Override
    public String next()
    {
        if (!hasNext())
            throw new NoSuchElementException();
        return array[currentIndex++];
    }

    @Override
    public void remove()
    {
        throw new UnsupportedOperationException();
    }
}

Upvotes: 3

Iterable interface will force your class to have a method iterator() this method must return an object of a class implementing the Iterator interface.

So your class ConjuntLlistaOrdenat1 must return an Iterator object which will be use to iterate over your list throught the methods hasNext() and next()

You have to implement this class and those two methods.

I find difficult to understand your code but I think your Iterator class could be an adapter of your ConjuntLlista.

Upvotes: 4

Related Questions