This seems like an easy thing to mess up, so I'd be grateful if you could think of any edge-cases that I've missed.public class StreamIterable<T> implements Iterable<T> {  private final Stream<T> stream;  public StreamIterable(Stream<T> stream) {    this.stream = stream;  }  @Override  public Iterator<T> iterator() {    return new StreamIterator<>(stream);  }}where public class StreamIterator<T> implements Iterator<T> {  private final Spliterator<T> spliterator;  private boolean nextIsKnown = false;  private T next = null;  public StreamIterator(Stream<T> stream) {    this.spliterator = stream.spliterator();  }  @Override  public boolean hasNext() {    if (nextIsKnown)        return true;    return spliterator.tryAdvance(t -> {next = t; nextIsKnown = true;});  }  @Override  public T next() {    if (nextIsKnown) {        return resetAndReturnNext();    }    if (!hasNext())        throw new NoSuchElementException();    return resetAndReturnNext();  }  private T resetAndReturnNext() {    T result = next;    nextIsKnown = false;    next = null;    return result;  }}Testspublic class StreamIteratableTest {    @Test    public void empty() {        assertThat(new StreamIterable<>(Stream.<String>empty()), Matchers.emptyIterable());    }    @Test    public void matcher() {        Stream<String> stream = Stream.of(1, 2, 3);        assertThat(new StreamIterable<>(stream), Matchers.contains(1, 2, 3));    }    @Test    public void torture_empty() {        StreamIterator<Object> empty = new StreamIterator<>(Stream.empty());        assertFalse(empty.hasNext());        try {            empty.next();            fail();        } catch (NoSuchElementException expected) {        }        assertFalse(empty.hasNext());        assertFalse(empty.hasNext());        try {            empty.next();            fail();        } catch (NoSuchElementException expected) {        }        try {            empty.next();            fail();        } catch (NoSuchElementException expected) {        }    }    @Test    public void dont_call_hasNext() {        StreamIterator<Object> twoItems = new StreamIterator<>(Stream.of(1, 2));        assertEquals(1, twoItems.next());        assertEquals(2, twoItems.next());        try {            twoItems.next();            fail();        } catch (NoSuchElementException expected) {        }    }    @Test    public void repeat_call_hasNext() {        StreamIterator<Object> twoItems = new StreamIterator<>(Stream.of(1, 2));        assertTrue(twoItems.hasNext());        assertTrue(twoItems.hasNext());        assertEquals(1, twoItems.next());        assertTrue(twoItems.hasNext());        assertEquals(2, twoItems.next());        assertFalse(twoItems.hasNext());        assertFalse(twoItems.hasNext());    }   }
StreamIterable - create an iterable from a Java 8 Stream
java;stream;iterator
Two things:I think you have missed the native implementation. Are you intentionally re-inventing the wheel? Streams have an iterator() method.Note that streams cannot be reversed, so, while you can create an iterator once, from the stream, you cannot create a second iterator.... In other words, you cannot loop more than once through your iterable.Consider reworking your class as:public class StreamIterable<T> implements Iterable<T> {  private final Stream<T> stream;  public StreamIterable(Stream<T> stream) {    this.stream = stream;  }  @Override  public Iterator<T> iterator() {    return stream.iterator();  }}That's it, no additional code needed. You can still only iterate it once, but, you can add the above to an enhanced-for loop:for (String v : new StreamIterable(Files.lines(...)) {    ....}