package edu.stanford.nlp.objectbank;
import java.io.*;
import java.util.*;
import java.util.function.Function;
import edu.stanford.nlp.util.AbstractIterator;
/**
* An Iterator that returns a line of a file at a time.
* Lines are broken as determined by Java's readLine() method.
* The returned lines do not include the newline character.
*
* @author Christopher Manning
*/
public class LineIterator<X> extends AbstractIterator<X> {
private final Function<String,X> op;
private final BufferedReader in;
private X nextToken; // = null;
@SuppressWarnings({"unchecked"})
public LineIterator(Reader r) {
this(r, new IdentityFunction()); // it seems like this can't be generified: seems a weird brokenness of Java to me! [cdm]
}
public LineIterator(Reader r, Function<String,X> op) {
this.op = op;
in = new BufferedReader(r);
setNext();
}
private void setNext() {
String line = null;
try {
line = in.readLine();
} catch (IOException ioe) {
ioe.printStackTrace();
}
if (line != null) {
nextToken = op.apply(line);
} else {
nextToken = null;
}
}
@Override
public boolean hasNext() {
return nextToken != null;
}
@Override
public X next() {
if (nextToken == null) {
throw new NoSuchElementException("LineIterator reader exhausted");
}
X token = nextToken;
setNext();
return token;
}
public Object peek() {
return nextToken;
}
/**
* Returns a factory that vends LineIterators that read the contents of the
* given Reader, splitting on newlines.
*
* @return An iterator over the lines of a file
*/
public static <X> IteratorFromReaderFactory<X> getFactory() {
return new LineIteratorFactory<>();
}
/**
* Returns a factory that vends LineIterators that read the contents of the
* given Reader, splitting on newlines.
*
* @param op A function to be applied to each line before it is returned
* @return An iterator over the lines of a file
*/
public static <X> IteratorFromReaderFactory<X> getFactory(Function<String,X> op) {
return new LineIteratorFactory<>(op);
}
public static class LineIteratorFactory<X> implements IteratorFromReaderFactory<X>, Serializable {
private static final long serialVersionUID = 1L;
@SuppressWarnings({"NonSerializableFieldInSerializableClass"})
private final Function<String,X> function;
@SuppressWarnings({"unchecked"})
public LineIteratorFactory() {
this(new IdentityFunction()); // it seems like this can't be generified: seems a weird brokenness of Java to me! [cdm]
}
public LineIteratorFactory(Function<String,X> op) {
this.function = op;
}
@Override
public Iterator<X> getIterator(Reader r) {
return new LineIterator<>(r, function);
}
}
}