бросая IOException во время итерации - PullRequest
0 голосов
/ 11 мая 2018

У меня есть LevelDBIterator, который я должен обернуть в свой собственный класс Java, который также реализует Iterator и использует LevelDBIterator внутри него. У меня есть 2 вопроса: 1. LevelDB выполняет чтение файла, поэтому метод, который читает из файловой системы, может вызвать IOException, как вызвать его в моем методе next()? Я спрашиваю об этом потому, что реализация Iterator не позволит мне выбросить исключение 2. Кроме того, как и когда закрыть базовый LevelDBIterator?

class Employee {
    String name;
    int age;
    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class MyIterator implements AutoCloseable, Iterator<Employee> {
    Iterator<Employee> it;
    public MyIterator(Iterator<Employee> it) {
        this.it = it;
    }
    @Override
    public void close() throws Exception {
        System.out.println("close called");
    }

    @Override
    public boolean hasNext() {
        return it.hasNext();
    }

    @Override
    public Employee next() {
        return it.next();
    }
}
public class EmployeeList implements AutoCloseable,Iterable<Employee>{
    List<Employee> emplist;
    @Override
    public Iterator<Employee> iterator() {

        return new Iterator<Employee>() {
            private final Iterator<Employee> it = emplist.iterator();
            @Override
            public boolean hasNext() {
                System.out.println("called hasNext");
                return it.hasNext();
            }

            @Override
            public Employee next() {
                return it.next();
            }
        };
    }

    public static void main(String[] args) {
        EmployeeList lst = new EmployeeList();
        lst.emplist = new ArrayList<>();
        lst.emplist.add(new Employee("name1", 10));
        lst.emplist.add(new Employee("name2", 20));
        lst.emplist.add(new Employee("name3", 30));
        System.out.println("Does close work?");
        try (MyIterator it = new MyIterator(lst.iterator())) {
           while(it.hasNext()) {
               System.out.println(it.next().name);
           }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void close() throws Exception {
        System.out.println("close called");
    }

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Q: Как вывести его в моем методе next ()?

A: Вы можете перехватить исключение, а затем выбросить непроверенное RuntimeException .


Q: Как закрыть базовый LevelDBIterator и когда?

A: Помимо реализации Iterator, вы реализуете AutoCloseable и документируете, что ваш итератор должен быть закрыт после использования.Затем пользователь вашего итератора может явно его закрыть или использовать try-with-resources .

0 голосов
/ 11 мая 2018

Если вы хотите реализовать Iterator, который требует закрытия ресурса в конце итерации, вы должны инкапсулировать это в объект, реализующий Iterable и AutoCloseable.

Например, если вы обычно делаете:

for (MyObj obj : xxx.getSomeResource()) {
    // code here
}

Затем измените код, чтобы вместо этого сделать это:

try (MyResource res = xxx.getSomeResource()) {
    for (MyObj obj : res) {
        // code here
    }
}

Где MyResource будет что-то вроде:

class MyResource implements AutoCloseable, Iterable<MyObj> {
    private final LevelDBIterator levelDBIterator;
    public MyResource(LevelDBIterator levelDBIterator) {
        this.levelDBIterator = levelDBIterator;
    }
    @Override
    public Iterator<MyObj> iterator() {
        return /*code here*/;
    }
    @Override
    public void close() throws Exception {
        this.levelDBIterator.close();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...