Skip to content

Commit

Permalink
rebase on master
Browse files Browse the repository at this point in the history
fix checkstyle error

use single class imports
  • Loading branch information
anantdamle committed May 29, 2024
1 parent 66e2c57 commit f0e50f8
Show file tree
Hide file tree
Showing 8 changed files with 648 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,9 @@
<contributor>
<name>Arturo Bernal</name>
</contributor>
<contributor>
<name>Anant Damle</name>
</contributor>
</contributors>

</project>
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/org/apache/commons/collections4/IterableUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

import org.apache.commons.collections4.functors.EqualPredicate;
import org.apache.commons.collections4.iterators.LazyIteratorChain;
import org.apache.commons.collections4.iterators.PairedIterator;
import org.apache.commons.collections4.iterators.PairedIterator.PairedItem;
import org.apache.commons.collections4.iterators.ReverseListIterator;
import org.apache.commons.collections4.iterators.UniqueFilterIterator;

Expand Down Expand Up @@ -622,6 +624,38 @@ public static <E> boolean matchesAny(final Iterable<E> iterable, final Predicate
return IteratorUtils.matchesAny(emptyIteratorIfNull(iterable), predicate);
}

/**
* Provides iteration over the elements contained in a pair of Iterables in-tandem.
* <p>
* The returned iterable has an iterator that traverses the elements in {@code a}
* and {@code b} together until one of the iterables is traversed completely.
* </p>
*
* <p>
* The returned iterable's iterator does NOT support {@code remove()}.
* </p>
*
* @param <L> the left elements' type
* @param <R> the right elements' type
* @param left the iterable for the left side elements
* @param right the iterable for the right side elements
* @return an iterable, over the decorated iterables to traverse them together until one is
* exhausted
* @throws NullPointerException if any iterator is null
* @since 4.5
*/
public static <L, R> Iterable<PairedItem<L, R>> pairedIterable(final Iterable<L> left, final Iterable<R> right) {
checkNotNull(left);
checkNotNull(right);

return new FluentIterable<PairedItem<L, R>>(){
@Override
public Iterator<PairedItem<L, R>> iterator() {
return IteratorUtils.pairedIterator(left.iterator(), right.iterator());
}
};
}

/**
* Partitions all elements from iterable into separate output collections,
* based on the evaluation of the given predicates.
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/org/apache/commons/collections4/IteratorUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.apache.commons.collections4.iterators.ObjectArrayIterator;
import org.apache.commons.collections4.iterators.ObjectArrayListIterator;
import org.apache.commons.collections4.iterators.ObjectGraphIterator;
import org.apache.commons.collections4.iterators.PairedIterator;
import org.apache.commons.collections4.iterators.PeekingIterator;
import org.apache.commons.collections4.iterators.PushbackIterator;
import org.apache.commons.collections4.iterators.SingletonIterator;
Expand Down Expand Up @@ -1056,6 +1057,26 @@ public static <E> Iterator<E> objectGraphIterator(final E root,
return new ObjectGraphIterator<>(root, transformer);
}

/**
* Gets an Iterator over the elements contained in a pair of Iterables in-tandem.
* <p>
* The returned iterator traverses the elements in {@code a} and {@code b} together until one of the iterators
* is exhausted.
* <p>
* The returned iterator does NOT support {@code remove()}.
*
* @param <L> the left elements' type
* @param <R> the right elements' type
* @param left the iterator for the left side elements
* @param right the iterator for the right side elements
* @return an iterator, to iterate over the decorated iterators together until one is exhausted
* @throws NullPointerException if any iterator is null
* @since 4.5
*/
public static <L, R> PairedIterator<L, R> pairedIterator(final Iterator<L> left, Iterator<R> right) {
return PairedIterator.of(left, right);
}

/**
* Gets an iterator that supports one-element lookahead.
*
Expand Down
100 changes: 100 additions & 0 deletions src/main/java/org/apache/commons/collections4/PairedIterable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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;

import org.apache.commons.collections4.iterators.PairedIterator;
import org.apache.commons.collections4.iterators.PairedIterator.PairedItem;

import java.util.Iterator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static java.util.Objects.requireNonNull;

/**
* Provides iteration over the elements contained in a pair of Iterables in-tandem.
*
* <p>
* Given two {@link Iterable} instances {@code A} and {@code B}, the {@link #iterator} method on this
* iterator provide a Pair of {@code A.next()} and {@code B.next()} until one of the iterators is
* exhausted.
* </p>
* This can simplify zipping over two iterables using the for-each construct.
* Example usage:
* <pre>{@code
* List<Integer> studentIds = ...
* List<String> studentNames = ...
*
* for (PairedItem<Integer, String> items : PairedIterable.of(studentIds, studentNames) {
* Integer studentId = item.getLeft();
* String studentName = item.getRight();
* ...
* }
* }</pre>
*
* @param <L> the left elements' type
* @param <R> the right elements' type
* @since 4.5
*/
public class PairedIterable<L, R> implements Iterable<PairedItem<L, R>> {

/**
* The left {@link Iterable}s to evaluate.
*/
private final Iterable<L> leftIterable;

/**
* The right {@link Iterable}s to evaluate.
*/
private final Iterable<R> rightIterable;

/**
* Constructs a new {@code PairedIterable} that will provide iteration over two given iterables.
*
* @param leftIterable the iterable for the left side element.
* @param rightIterable the iterable for the right side element.
* @throws NullPointerException if either iterator is null
* @since 4.5
*/
public PairedIterable(Iterable<L> leftIterable, Iterable<R> rightIterable) {
this.leftIterable = requireNonNull(leftIterable);
this.rightIterable = requireNonNull(rightIterable);
}

/**
* Convenience static factory to construct the PairedIterable from provided
* {@link Iterable} sources.
*
* @param leftIterable the iterable for the left side element.
* @param rightIterable the iterable for the right side element.
* @return the Iterable to iterate over the elements derived from the provided iterables.
* @throws NullPointerException if either iterables is null
* @since 4.5
*/
public static <L, R> PairedIterable<L, R> of(Iterable<L> leftIterable, Iterable<R> rightIterable) {
return new PairedIterable<>(leftIterable, rightIterable);
}

@Override
public Iterator<PairedItem<L, R>> iterator() {
return PairedIterator.ofIterables(leftIterable, rightIterable);
}

public Stream<PairedItem<L, R>> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* 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 java.util.Objects.requireNonNull;

import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.commons.collections4.iterators.PairedIterator.PairedItem;

/**
* Provides a iteration over the elements contained in a pair of Iterators.
*
* <p>
* Given two {@link Iterator} instances {@code A} and {@code B}, the {@link #next} method on this
* iterator provide a Pair of {@code A.next()} and {@code B.next()} until one of the iterators is
* exhausted.
* </p>
* Example usage:
* <pre>{@code
* List<Integer> studentIds = ...
* List<String> studentNames = ...
*
* PairedIterator<PairedItem<Integer, String>> pairedIterator =
* PairedIterator.ofIterables(studentIds, studentNames);
*
* while (pairedIterator.hasNext()) {
* PairedItem<Integer, String> item = pairedIterator.next();
* ...
* }
* }</pre>
*
* @param <L> the left elements' type
* @param <R> the right elements' type
* @since 4.5
*/
public class PairedIterator<L, R> implements Iterator<PairedItem<L, R>> {

/**
* The left {@link Iterator}s to evaluate.
*/
private final Iterator<L> leftIterator;

/**
* The right {@link Iterator}s to evaluate.
*/
private final Iterator<R> rightIterator;

/**
* Constructs a new {@code ZipPairIterator} that will provide iteration over the two given
* iterators.
*
* @param leftIterator the iterator for the left side element.
* @param rightIterator the iterator for the right side element.
* @throws NullPointerException if either iterator is null
* @since 4.5
*/
public PairedIterator(Iterator<L> leftIterator, Iterator<R> rightIterator) {
this.leftIterator = requireNonNull(leftIterator);
this.rightIterator = requireNonNull(rightIterator);
}

/**
* Convenience static factory to construct the ZipPairIterator
*
* @param leftIterator the iterator for the left side element.
* @param rightIterator the iterator for the right side element.
* @return the iterator to iterate over the provided iterators.
* @throws NullPointerException if either iterator is null
* @since 4.5
*/
public static <L, R> PairedIterator<L, R> of(Iterator<L> leftIterator, Iterator<R> rightIterator) {
return new PairedIterator<>(leftIterator, rightIterator);
}

/**
* Convenience static factory to construct the ZipPairIterator from any {@link Iterable} sources.
*
* @param leftIterable the iterable for the left side element.
* @param rightIterable the iterable for the right side element.
* @return the iterator to iterate over the iterators derived from the provided iterables.
* @throws NullPointerException if either iterables is null
* @since 4.5
*/
public static <L, R> PairedIterator<L, R> ofIterables(Iterable<L> leftIterable, Iterable<R> rightIterable) {
return of(requireNonNull(leftIterable).iterator(), requireNonNull(rightIterable).iterator());
}

/**
* Returns {@code true} if both the child iterators have remaining elements.
*
* @return true if both the child iterators have remaining elements
*/
@Override
public boolean hasNext() {
return leftIterator.hasNext() && rightIterator.hasNext();
}

/**
* Returns the next elements from both the child iterators.
*
* @return the next elements from both the iterators.
* @throws NoSuchElementException if any one child iterator is exhausted.
*/
@Override
public PairedItem<L, R> next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return PairedItem.of(leftIterator.next(), rightIterator.next());
}

/**
* An immutable tuple class to represent elements from both the iterators.
*
* @param <L> the left elements' type
* @param <R> the right elements' type
* @since 4.5
*/
public static final class PairedItem<L, R> {

private final L leftItem;

private final R rightItem;

private PairedItem(L leftItem, R rightItem) {
this.leftItem = leftItem;
this.rightItem = rightItem;
}

/**
* Convenience static factory method to construct the tuple pair.
*
* @param left the left element
* @param right the right element
* @return the Immutable tuple pair of two elements.
*/
private static <L, R> PairedItem<L, R> of(L left, R right) {
return new PairedItem<>(left, right);
}

public L getLeftItem() {
return leftItem;
}

public R getRightItem() {
return rightItem;
}

@Override
public String toString() {
return String.format("{%s, %s}", leftItem, rightItem);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.apache.commons.collections4.iterators.EnumerationIterator;
import org.apache.commons.collections4.iterators.NodeListIterator;
import org.apache.commons.collections4.iterators.ObjectArrayIterator;
import org.apache.commons.collections4.iterators.PairedIterator;
import org.apache.commons.collections4.iterators.ZippingIterator;
import org.apache.commons.collections4.map.EntrySetToMapIteratorAdapter;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -1116,4 +1117,11 @@ public void testZippingIterator() {
assertTrue(IteratorUtils.zippingIterator(iterator, iterator) instanceof ZippingIterator, "create instance fail");
}

@Test
public void testPairedIterator() {
final ArrayList<String> stringList = new ArrayList<>();
final ArrayList<Integer> integerList = new ArrayList<>();

assertTrue(IteratorUtils.pairedIterator(stringList.iterator(), integerList.iterator()) instanceof PairedIterator, "create instance failed");
}
}
Loading

0 comments on commit f0e50f8

Please sign in to comment.