001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.io.function; 019 020import java.io.IOException; 021import java.io.UncheckedIOException; 022import java.util.Iterator; 023import java.util.NoSuchElementException; 024import java.util.Objects; 025import java.util.function.Consumer; 026 027/** 028 * Like {@link Iterator} but throws {@link IOException}. 029 * 030 * @param <E> the type of elements returned by this iterator. 031 * @since 2.12.0 032 */ 033public interface IOIterator<E> { 034 035 /** 036 * Adapts the given Iterable as an IOIterator. 037 * 038 * @param <E> the type of the stream elements. 039 * @param iterable The iterable to adapt 040 * @return A new IOIterator 041 * @since 2.17.0 042 */ 043 static <E> IOIterator<E> adapt(final Iterable<E> iterable) { 044 return IOIteratorAdapter.adapt(iterable.iterator()); 045 } 046 047 /** 048 * Adapts the given Iterator as an IOIterator. 049 * 050 * @param <E> the type of the stream elements. 051 * @param iterator The iterator to adapt 052 * @return A new IOIterator 053 */ 054 static <E> IOIterator<E> adapt(final Iterator<E> iterator) { 055 return IOIteratorAdapter.adapt(iterator); 056 } 057 058 /** 059 * Creates an {@link Iterator} for this instance that throws {@link UncheckedIOException} instead of 060 * {@link IOException}. 061 * 062 * @return an {@link UncheckedIOException} {@link Iterator}. 063 */ 064 default Iterator<E> asIterator() { 065 return new UncheckedIOIterator<>(this); 066 } 067 068 /** 069 * Like {@link Iterator#forEachRemaining(Consumer)}. 070 * 071 * @param action See delegate. 072 * @throws IOException if an I/O error occurs. 073 */ 074 default void forEachRemaining(final IOConsumer<? super E> action) throws IOException { 075 Objects.requireNonNull(action); 076 while (hasNext()) { 077 action.accept(next()); 078 } 079 } 080 081 /** 082 * Like {@link Iterator#hasNext()}. 083 * 084 * @return See delegate. 085 * @throws IOException if an I/O error occurs. 086 */ 087 boolean hasNext() throws IOException; 088 089 /** 090 * Like {@link Iterator#next()}. 091 * 092 * @return See delegate. 093 * @throws IOException if an I/O error occurs. 094 * @throws NoSuchElementException if the iteration has no more elements 095 */ 096 E next() throws IOException; 097 098 /** 099 * Like {@link Iterator#remove()}. 100 * 101 * @throws IOException if an I/O error occurs. 102 */ 103 @SuppressWarnings("unused") 104 default void remove() throws IOException { 105 unwrap().remove(); 106 } 107 108 /** 109 * Unwraps this instance and returns the underlying {@link Iterator}. 110 * <p> 111 * Implementations may not have anything to unwrap and that behavior is undefined for now. 112 * </p> 113 * @return the underlying Iterator. 114 */ 115 Iterator<E> unwrap(); 116 117}