tipos - sobreescribir un archivo en java
Iteradores para leer y procesar archivos en Java (3)
Desde el punto de vista de la memoria, realmente no se guardará ninguna memoria mediante el uso de iteradores. Supongo que leerá todos los puntos en la memoria, por lo que todos tendrán que almacenarse de alguna manera.
Un iterador no es un tipo de colección diferente: simplemente es una forma diferente de iterar a través de una colección. Por ejemplo, puede ir a list.iterator()
para hacer que un iterador list.iterator()
su lista (o cualquier colección).
La elección de qué colección usar para mantener todos los puntos en la memoria es la que afectará a la memoria (por ejemplo, ArrayList
vs. LinkedList
).
Supongamos que tengo un Point
clase y una función para procesar instancias de Point
class Point { private final int x, y; ... } ... void handlePoints(Iterable<Point> points) { for (Point p: points) {...} }
Ahora me gustaría leer los points
de un archivo. Cada línea del archivo contiene dos números, por lo que tengo una función ("método de fábrica") para crear un point
partir de una línea.
Point makePoint(String line) { ... }
¿Qué debería hacer ahora? Puedo escribir una función para leer el archivo en una lista de points
y llamar a la función handlePoints
.
List<Point> readPoints(BufferedReader reader) {...} // use makePoint here void handlePoints(BufferedReader reader) { List<Point> points = readPoints(reader); handlePoints(points); }
Desafortunadamente, esta función no parece particularmente elegante ya que crea una lista innecesaria de puntos en la memoria.
¿No sería mejor usar iteradores ?
void handlePoints(Iterator<Point> points) {...} Iterator<Point> readPoints(BufferedReader reader) {...} // use makePoint here void handlePoints(BufferedReader reader) { Iterator<Point> points = readPoints(reader); handlePoints(points); }
¿Tiene sentido? ¿No será este código demasiado "ruidoso" en Java?
Si no necesita tener todos los puntos en la memoria, piense en algo más en esta línea:
while (reader.ready())
{
String line = reader.readLine();
Point point = makePoint(line);
handlePoint(point);
}
Cómo hacer esto con un iterador y handlePoints: (código para manejar las excepciones que se agregarán)
class PointIterator implements Iterator<Point>
{
BufferedReader reader;
PointIterator(BufferedReader myReader) { reader = myReader; };
@Override
public boolean hasNext() { return myReader.ready(); };
@Override
public Point next() { return makePoint(myReader.readLine()); };
@Override
public void remove()
{ throw new UnsupportedOperationException("Remove not supported!"); };
}
Y porque handlePoints
toma un Iterable
:
class PointIterable implements Iterable<Point>
{
BufferedReader reader;
public PointIterable(BufferedReader myReader) { reader = myReader; };
@Override
public Iterator<Point> iterator() { return new PointIterator(reader); }
}
Usar:
handlePoints(new PointIterable(reader));
Solo lea una vez del archivo y consérvelo en la memoria en lugar de leer cada vez desde el archivo
List<Points> points ;
public List<Point> readPoints(BufferedReader reader) {
if(points == null) {
points = new ArrayList();
// read from file and populate
points.add(point) ;
}
return points;
}