You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Claudenw (via GitHub)" <gi...@apache.org> on 2024/10/20 09:26:20 UTC
[PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Claudenw opened a new pull request, #564:
URL: https://github.com/apache/commons-collections/pull/564
fix for COLLECTIONS-870
Adds an ExtendedIterator as defined in COLLECTIONS-870 as well as in the discussion on the mailing list.
mailing list discussion: https://lists.apache.org/thread/rpcsoz3jwz7x9sp3cgzf315ls7pcd90w
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1809117741
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
`setFunction()` ? This class does not track a function that I can see.
There is just too much duplication with `FilterIterator` to avoid subclassing IMO. Having 2 almost identical classes feels confusing IMO.
I could even see initially creating a subclass and then considering pulling up the functionality into FilterIterator. The cuurent FilterIterator already does more than a plain "Filter" in the traditional `Filter[Input|Output]Stream` model (The same model we follow Commons IO where we provide subclasses to `Filter[Input|Output]Stream` (most) extending `Proxy[Input|Output]Stream`.)
As an aside, ideally, the FilterIterator class should have been immutable, or that's what I would do if I were to write one today, but that's beside the point IMO. I say this as I do not think we want to add more mutable state.
Maybe I'll experiment later ;-)...
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1810761131
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
OK. Let me start again.
EnhancedIterator is an Iterator that adds Streaming like functionality (e.g. filter, map, etc.).
By that definition it should have methods like `filter(Predicate)`, `map(Function)`, etc. (Note Predicate and Function are the java classes not the org.apache.commons based ones).
I would not expect it to have methods like `setFilter(Predicate)` or `setFunction(Function)`
If EnhancedIterator extends FilterIterator it exposes 2 undesirable methods. `setPredicate(Predicate)` (apache commons based class) and `setIterator(Iterator)`.
EnhancedIterator does not really extend FilterIterator in concept, and adding FilterIterator as a super class to remove a few lines of code is a bad idea as it just muddies the water.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1809117741
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
`setFunction()` ? This class does not track a function that I can see.
There is just too much duplication with `FilterIterator` to avoid subclassing IMO. Having 2 almost identical classes feels confusing IMO.
I could even see initially creating a subclass and then considering pulling up the functionality into FilterIterator. The cuurent FilterIterator already does more than a plain "Filter" in the traditional `Filter[Input|Output]Stream` model (The same model we follow Commons IO where we provide subclasses to `Filter[Input|Output]Stream` (most) extending `Proxy[Input|Output]Stream`.)
As an aside, ideally, the FilterIterator class should have been immutable, or that's what I would do if I were to write one today, but that's beside the point IMO. I say this as I do not think we want to add more mutable state.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1809612478
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
This class does not track a function unless you consider the `map()` method. It doesn't track a Predicate either, unless you consider the `filter()` method. Extended iterator only adds the ability to force an iterator to not support delete. All other methods simply create instances of other collection iterator classes. Am I missing something here?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1820365741
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
@garydgregory Did you see my comment above?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1820699573
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
Hi @Claudenw,
> EnhancedIterator is an Iterator that adds Streaming like functionality
This is causing me to pause and think that adding streaming-like functionality here is the wrong way to go. Instead of adding a 2 or 3 methods now and who knows how many later, and considering that the `Stream` interface and functionality is large and rich, so instead of inventing a new vocabulary here, why not just use a `Stream`? We could instead add:
- org.apache.commons.collections4.IteratorUtils.stream(Iterable<E>)
- org.apache.commons.collections4.IteratorUtils.stream(Iterator<E>)
This provides a bridge to the full Stream functionality, which everyone is familiar with, no need to add and learn new custom methods like "addTo", "map", and so on.
Details: Something like
```java
/**
* Creates a stream on the given Iterable.
*
* @param <E> the type of elements in the Iterable.
* @param iterable the Iterable to stream or null.
* @return a new Stream or {@link Stream#empty()} if the Iterable is null.
* @since 4.5.0-M3
*/
public static <E> Stream<E> stream(final Iterable<E> iterable) {
return iterable == null ? Stream.empty() : StreamSupport.stream(iterable.spliterator(), false);
}
/**
* Creates a stream on the given Iterator.
*
* @param <E> the type of elements in the Iterator.
* @param iterator the Iterator to stream or null.
* @return a new Stream or {@link Stream#empty()} if the Iterator is null.
* @since 4.5.0-M3
*/
public static <E> Stream<E> stream(final Iterator<E> iterator) {
return iterator == null ? Stream.empty() : StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
}
```
Such that you get:
```java
@Test
public void testCollect() {
List<Integer> expected = new ArrayList<>(collectionA);
expected.addAll(collectionA);
// stream-like: List<Integer> actual = ExtendedIterator.create(collectionA.iterator()).addTo(new ArrayList<>(collectionA));
// real stream:
List<Integer> actual1 = IteratorUtils.stream(collectionA).collect(Collectors.toCollection(() -> new ArrayList<>(collectionA)));
assertEquals(expected, actual1);
List<Integer> actual2 = IteratorUtils.stream(collectionA.iterator()).collect(Collectors.toCollection(() -> new ArrayList<>(collectionA)));
assertEquals(expected, actual2);
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1808844173
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
+
+ /**
+ * Initialise this wrapping with the given base iterator and remove-control.
+ * @param base the base iterator that this iterator wraps
+ * @param removeDenied true if .remove() must throw an exception
+ */
+ private ExtendedIterator(final Iterator<? extends T> base, final boolean removeDenied) {
+ this.base = base;
+ this.removeDenied = removeDenied;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return base.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return base.next();
+ }
+
+ @Override
+ public void forEachRemaining(final Consumer<? super T> action) {
+ base.forEachRemaining(action);
+ }
+
+ @Override
+ public void remove() {
+ if (removeDenied) {
+ throw new UnsupportedOperationException();
+ }
+ base.remove();
+ }
+
+ /**
+ * Returns the next item and removes it from the iterator.
+ * @return the next item from the iterator.
+ */
+ public T removeNext() {
+ T result = next();
+ remove();
+ return result;
+ }
+
+ /**
+ * Chains the {@code other} iterator to the end of this one.
+ * @param other the other iterator to extend this iterator with.
+ * @return A new iterator returning the contents of {@code this} iterator followed by the contents of {@code other} iterator.
+ * @param <X> The type of object returned from the other iterator.
+ */
+ public <X extends T> ExtendedIterator<T> andThen(final Iterator<X> other) {
+ if (base instanceof IteratorChain) {
+ ((IteratorChain<T>) base).addIterator(other);
+ return this;
+ }
+ return new ExtendedIterator<T>(new IteratorChain<T>(this.base, other), this.removeDenied);
+ }
+
+ /**
+ * Filter this iterator using a predicate. Only items for which the predicate returns {@code true} will
+ * be included in the result.
+ * @param predicate The predicate to filter the items with.
+ * @return An iterator filtered by the predicate.
+ */
+ public ExtendedIterator<T> filter(final Predicate<T> predicate) {
Review Comment:
see above.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1809612478
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
This class does not track a function. Extended iterator only adds the ability to force an iterator to not support delete. All other methods simply create instances of other collection iterator classes. Am I missing something here?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on PR #564:
URL: https://github.com/apache/commons-collections/pull/564#issuecomment-2439539460
I responded to this on github but it does not seem to have come through
here.
On Tue 22 Oct 2024, 12:20 Gary Gregory, ***@***.***> wrote:
> ***@***.**** commented on this pull request.
> ------------------------------
>
> In
> src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java
> <https://github.com/apache/commons-collections/pull/564#discussion_r1810533509>
> :
>
> > +
> + /**
> + * Create an ExtendedIterator returning the elements of <code>it</code>.
> + * If <code>it</code> is itself an ExtendedIterator, return that;
> + * otherwise wrap <code>it</code>.
> + * @param it The iterator to wrap.
> + * @return An Extended iterator wrapping ***@***.*** it}
> + */
> + public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
> + return it instanceof ExtendedIterator<?>
> + ? (ExtendedIterator<T>) it
> + : new ExtendedIterator<>(it, false);
> + }
> +
> + /** the base iterator that we wrap */
> + private final Iterator<? extends T> base;
>
> Hi @Claudenw <https://github.com/Claudenw>
> You wrote:
>
> If we do this then why not expose setFunction() and something else for
> andThen().
>
> Which is why I asked about setFunction(). Maybe I'm the one missing
> something? 🤔
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/apache/commons-collections/pull/564#discussion_r1810533509>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AASTVHWDUPBUIJH4RO33A73Z4YYGHAVCNFSM6AAAAABQIKXUCCVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDGOBUHA4DOMZRHA>
> .
> You are receiving this because you were mentioned.Message ID:
> ***@***.***>
>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1808791866
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
Extending `FilterIterator` exposes `setIterator()` and `setPredicate()` and changes the semantics of the class.
If we do this then why not expose `setFunction()` and something else for `andThen()`.
I think the semantics are cleaner if we do not extend FilterIterator but use it instead.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1810533509
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
Hi @Claudenw
You wrote:
> If we do this then why not expose setFunction() and something else for andThen().
Which is why I asked about `setFunction()`. Maybe I'm the one missing something? 🤔
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1807784186
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
Review Comment:
Add `@since 4.5.0-M3`.
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
Review Comment:
I would either fix "A" -> "An" or just say "Extends functionality to do ..."
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
Extend `FilterIterator` and you don't need this and most other delegating methods.
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
Review Comment:
IMO "Denied" could imply noop, so I would be explicit and call it "throwOnRemove".
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
+
+ /**
+ * Initialise this wrapping with the given base iterator and remove-control.
+ * @param base the base iterator that this iterator wraps
+ * @param removeDenied true if .remove() must throw an exception
+ */
+ private ExtendedIterator(final Iterator<? extends T> base, final boolean removeDenied) {
+ this.base = base;
+ this.removeDenied = removeDenied;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return base.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return base.next();
+ }
+
+ @Override
+ public void forEachRemaining(final Consumer<? super T> action) {
+ base.forEachRemaining(action);
+ }
+
+ @Override
+ public void remove() {
+ if (removeDenied) {
+ throw new UnsupportedOperationException();
+ }
+ base.remove();
+ }
+
+ /**
+ * Returns the next item and removes it from the iterator.
+ * @return the next item from the iterator.
+ */
+ public T removeNext() {
+ T result = next();
+ remove();
+ return result;
+ }
+
+ /**
+ * Chains the {@code other} iterator to the end of this one.
+ * @param other the other iterator to extend this iterator with.
+ * @return A new iterator returning the contents of {@code this} iterator followed by the contents of {@code other} iterator.
+ * @param <X> The type of object returned from the other iterator.
+ */
+ public <X extends T> ExtendedIterator<T> andThen(final Iterator<X> other) {
+ if (base instanceof IteratorChain) {
+ ((IteratorChain<T>) base).addIterator(other);
+ return this;
+ }
+ return new ExtendedIterator<T>(new IteratorChain<T>(this.base, other), this.removeDenied);
+ }
+
+ /**
+ * Filter this iterator using a predicate. Only items for which the predicate returns {@code true} will
+ * be included in the result.
+ * @param predicate The predicate to filter the items with.
+ * @return An iterator filtered by the predicate.
+ */
+ public ExtendedIterator<T> filter(final Predicate<T> predicate) {
Review Comment:
Extend `FilterIterator` and you don't need this.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory merged PR #564:
URL: https://github.com/apache/commons-collections/pull/564
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1820658056
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * Extends Iterator functionality to include operations commonly found on streams (e.g. filtering, concatenating, mapping).
+ * It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ * @since 4.5.0-M3
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean throwOnRemove;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
Review Comment:
Hi @Claudenw
If you rebase on git master, you can say:
```java
return create(IteratorUtils.chainedIterator(iterators));
```
instead of:
```
return create(new LazyIteratorChain<T>() {
@Override
protected Iterator<? extends T> nextIterator(final int count) {
return iterators.hasNext() ? iterators.next() : null;
}
});
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1819074668
##########
src/test/java/org/apache/commons/collections4/iterators/ExtendedIteratorTest.java:
##########
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.collections4.iterators;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class ExtendedIteratorTest {
Review Comment:
I just realized this test should extent `AbstractIteratorTest`, especially now that I added testing `forEachRemaining()`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1819280169
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * Extends Iterator functionality to include operations commonly found on streams (e.g. filtering, concatenating, mapping).
+ * It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ * @since 4.5.0-M3
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean throwOnRemove;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
Review Comment:
Missing Javadoc for `T`.
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * Extends Iterator functionality to include operations commonly found on streams (e.g. filtering, concatenating, mapping).
+ * It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ * @since 4.5.0-M3
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean throwOnRemove;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
Review Comment:
Needs generics IMO (not `?`).
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * Extends Iterator functionality to include operations commonly found on streams (e.g. filtering, concatenating, mapping).
+ * It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ * @since 4.5.0-M3
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean throwOnRemove;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
Review Comment:
Missing Javadoc for `T`.
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * Extends Iterator functionality to include operations commonly found on streams (e.g. filtering, concatenating, mapping).
+ * It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ * @since 4.5.0-M3
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean throwOnRemove;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
Review Comment:
Missing Javadoc for `T`.
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * Extends Iterator functionality to include operations commonly found on streams (e.g. filtering, concatenating, mapping).
+ * It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ * @since 4.5.0-M3
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean throwOnRemove;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
Review Comment:
Missing Javadoc for `T`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "garydgregory (via GitHub)" <gi...@apache.org>.
garydgregory commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1820699573
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
+
+ /**
+ * Creates an ExtendedIterator wrapped round <code>it</code>,
+ * which does not permit <code>.remove()</code>
+ * even if <code>it</code> does.
+ * @param it The Iterator to wrap.
+ * @return an Extended iterator on {@code it}
+ * @throws UnsupportedOperationException if remove() is called on the resulting iterator.
+ */
+ public static <T> ExtendedIterator<T> createNoRemove(final Iterator<T> it) {
+ return new ExtendedIterator<>(it, true);
+ }
+
+ /**
+ * Creates an ExtendedIterator wrapped round a {@link Stream}.
+ * The extended iterator does not permit <code>.remove()</code>.
+ * <p>
+ * The stream should not be used directly. The effect of doing so is
+ * undefined.
+ * </p>
+ * @param stream the Stream to create an iterator from.
+ * @return an Extended iterator on the {@code stream} iterator.
+ */
+ public static <T> ExtendedIterator<T> create(final Stream<T> stream) {
+ return new ExtendedIterator<T>(stream.iterator(), true);
+ }
+
+ /**
+ * Flattens an iterator of iterators into an Iterator over the next level values.
+ * Similar to list splicing in lisp.
+ * @param iterators An iterator of iterators.
+ * @return An iterator over the logical concatenation of the inner iterators.
+ */
+ public static <T> ExtendedIterator<T> flatten(final Iterator<Iterator<T>> iterators) {
+ return create(new LazyIteratorChain<T>() {
+
+ @Override
+ protected Iterator<? extends T> nextIterator(final int count) {
+ return iterators.hasNext() ? iterators.next() : null;
+ }
+
+ });
+ }
+
+ /**
+ * Creates an empty Extended iterator.
+ * @return An empty Extended iterator.
+ */
+ public static ExtendedIterator<?> emptyIterator() {
+ return new ExtendedIterator<>(Collections.emptyIterator(), false);
+ }
+
+ /**
+ * Create an ExtendedIterator returning the elements of <code>it</code>.
+ * If <code>it</code> is itself an ExtendedIterator, return that;
+ * otherwise wrap <code>it</code>.
+ * @param it The iterator to wrap.
+ * @return An Extended iterator wrapping {@code it}
+ */
+ public static <T> ExtendedIterator<T> create(final Iterator<T> it) {
+ return it instanceof ExtendedIterator<?>
+ ? (ExtendedIterator<T>) it
+ : new ExtendedIterator<>(it, false);
+ }
+
+ /** the base iterator that we wrap */
+ private final Iterator<? extends T> base;
Review Comment:
Hi @Claudenw,
> EnhancedIterator is an Iterator that adds Streaming like functionality
This is causing me to pause and think that adding streaming-like functionality here is the wrong way to go. Instead of adding a 2 or 3 methods now and who knows how many later, and considering that the `Stream` interface and functionality is large and rich, so instead of inventing a new vocabulary here, why not just use a `Stream`? We could instead add:
- org.apache.commons.collections4.IteratorUtils.stream(Iterable<E>)
- org.apache.commons.collections4.IteratorUtils.stream(Iterator<E>)
This provides a bridge to the full Stream functionality, which everyone is familiar with, no need to add and learn new custom methods like "addTo", "map", and so on.
Details: Something like
```java
/**
* Creates a stream on the given Iterable.
*
* @param <E> the type of elements in the Iterable.
* @param iterable the Iterable to stream or null.
* @return a new Stream or {@link Stream#empty()} if the Iterable is null.
* @since 4.5.0-M3
*/
public static <E> Stream<E> stream(final Iterable<E> iterable) {
return iterable == null ? Stream.empty() : StreamSupport.stream(iterable.spliterator(), false);
}
/**
* Creates a stream on the given Iterator.
*
* @param <E> the type of elements in the Iterator.
* @param iterator the Iterator to stream or null.
* @return a new Stream or {@link Stream#empty()} if the Iterator is null.
* @since 4.5.0-M3
*/
public static <E> Stream<E> stream(final Iterator<E> iterator) {
return iterator == null ? Stream.empty() : StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] COLLECTIONS-870: Added ExtendedIterator and tests [commons-collections]
Posted by "Claudenw (via GitHub)" <gi...@apache.org>.
Claudenw commented on code in PR #564:
URL: https://github.com/apache/commons-collections/pull/564#discussion_r1808843509
##########
src/main/java/org/apache/commons/collections4/iterators/ExtendedIterator.java:
##########
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections4.iterators;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+
+/**
+ * A ExtendedIterator is an Iterator wrapping around a plain
+ * (or presented as plain) Iterator. The wrapping allows the usual
+ * operations found on streams (filtering, concatenating, mapping) to be done on an Iterator derived
+ * from some other source. It also provides convenience methods for common operations.
+ * @param <T> The type of object returned from the iterator.
+ */
+public final class ExtendedIterator<T> implements Iterator<T> {
+ /**
+ * Set to <code>true</code> if this wrapping doesn't permit the use of
+ * {@link #remove()}, otherwise removal is delegated to the base iterator.
+ */
+ private final boolean removeDenied;
Review Comment:
changed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org