A Closeable iterator is an iterator that is auto closeable (implements java.lang.AutoCloseable interface). A typical use case of this iterator is for those are based on native-resources such as files, network, or database connections.
This is continuation to my previous post How to read the file in iterator way in Java?
What is iterator?
Iterator is used to traverse the collection of elements. There is also a legacy class called Enumeration, it is also used to traverse collection of elements. Only difference is by using iterator you can remove an element while traversing, by using enumerator you can’t.
Let me brief the methods in iterator interface.
Method |
Description |
boolean hasNext() |
Returns true if the iteration has more elements. |
E next() |
Returns the next element in the iteration. |
default void remove() |
Removes from the underlying collection the last element returned by this iterator. Java provides default implementation for this method. The default implementation throws an instance of UnsupportedOperationException and performs no other action. |
Iterable interface
All the Java collections implementing Iterable interface, to return an iterator. Implementing this interface allows an object to be the target of the "foreach" statement. Following table summarizes the methods in Iterable interface.
Method |
Description |
Iterator<T> iterator() |
Returns an iterator over a set of elements of type T. |
Now let’s come to the problem, I want to implement my a closeable iterator that close the resources automatically (when used I try-with resources statement) post reading the iterator elements.
Follow below step-by-step procedure to build a Closeable iterator.
Step 1: Define CloseableIterator interface.
CloseableIterator.java
package com.sample.app;
import java.util.Iterator;
public interface CloseableIterator<T> extends Iterator<T>, AutoCloseable{
static <T> CloseableIterator<T> getIterator(Iterator<T> iterator, AutoCloseable autoCloseable){
return new CloseableIteratorImpl<>(iterator, autoCloseable);
}
}
Step 2: Implement CloseableIterator interface.
CloseableIteratorImpl.java
package com.sample.app;
import java.util.Iterator;
public class CloseableIteratorImpl<T> implements CloseableIterator<T> {
private Iterator<T> iterator;
private AutoCloseable autoCloseable;
public CloseableIteratorImpl(Iterator<T> iterator, AutoCloseable autoCloseable) {
this.iterator = iterator;
this.autoCloseable = autoCloseable;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public T next() {
return iterator.next();
}
@Override
public void remove() {
iterator.remove();
}
@Override
public void close() throws Exception {
System.out.println("Closing "+ autoCloseable);
autoCloseable.close();
}
}
Step 3: Define FileReadIterable class. It is used to read the file content in iterator fashion.
FileReadIterable.java
package com.sample.app;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Iterator;
/**
* FileReadIterable class is used to read the file using an iterator.
*/
public class FileReadIterable implements Iterable<String> {
private BufferedReader bufferedReader;
public FileReadIterable(BufferedReader bufferedReader) {
this.bufferedReader = bufferedReader;
}
@Override
public Iterator<String> iterator() {
return new FileReadIterator(bufferedReader);
}
private static class FileReadIterator implements Iterator<String> {
private BufferedReader bufferedReader;
private String line;
public FileReadIterator(BufferedReader bufferedReader) {
this.bufferedReader = bufferedReader;
}
@Override
public boolean hasNext() {
try {
line = bufferedReader.readLine();
} catch (IOException e) {
return false;
}
return line != null;
}
@Override
public String next() {
return line;
}
}
}
Step 4: Create demo.txt file.
demo.txt
line1 line2 line3
Step 5: Define CloseableIteratorDemo class.
CloseableIteratorDemo.java
package com.sample.app;
import java.io.BufferedReader;
import java.io.FileReader;
import java.net.URL;
import java.util.Iterator;
public class CloseableIteratorDemo {
public static String resourceFilePath(String resourceFile) {
ClassLoader classLoader = FileIteratorDemo.class.getClassLoader();
URL url = classLoader.getResource(resourceFile);
return url.getPath();
}
public static void main(String[] args) throws Exception {
String filePath = resourceFilePath("demo.txt");
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
FileReadIterable fileReadIterable = new FileReadIterable(bufferedReader);
Iterator<String> fileIterator = fileReadIterable.iterator();
try (CloseableIterator<String> iterator = CloseableIterator.getIterator(fileIterator, bufferedReader)) {
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
}
Output
line1 line2 line3 Closing java.io.BufferedReader@15db9742
You may like
Can I run a class file that is compiled in lower environment?
How to solve the Error: Could not find or load main?
No comments:
Post a Comment