All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.weld.util.collections.Iterators Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2014, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * Licensed 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.jboss.weld.util.collections;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;

import org.jboss.weld.exceptions.UnsupportedOperationException;
import org.jboss.weld.util.Function;
import org.jboss.weld.util.Preconditions;

/**
 * Static utility methods for {@link Iterator}.
 *
 * @author Martin Kouba
 */
public final class Iterators {

    private Iterators() {
    }

    /**
     * Add all elements in the iterator to the collection.
     *
     * @param target
     * @param iterator
     * @return true if the target was modified, false otherwise
     */
    public static  boolean addAll(Collection target, Iterator iterator) {
        Preconditions.checkArgumentNotNull(target, "target");
        boolean modified = false;
        while (iterator.hasNext()) {
            modified |= target.add(iterator.next());
        }
        return modified;
    }

    /**
     * Combine the iterators into a single one.
     *
     * @param iterators An iterator of iterators
     * @return a single combined iterator
     */
    public static  Iterator concat(Iterator> iterators) {
        Preconditions.checkArgumentNotNull(iterators, "iterators");
        return new CombinedIterator(iterators);
    }

    /**
     *
     * @param iterator
     * @param function
     * @return an iterator that applies the given function to each element of the original iterator
     */
    public static  Iterator transform(final Iterator iterator, final Function function) {
        Preconditions.checkArgumentNotNull(iterator, "iterator");
        Preconditions.checkArgumentNotNull(function, "function");
        return new TransformingIterator(iterator, function);
    }

    static class CombinedIterator implements Iterator {

        private final Iterator> iterators;

        private Iterator current;

        private Iterator removeFrom;

        CombinedIterator(Iterator> iterators) {
            this.iterators = iterators;
            this.current = Collections.emptyIterator();
        }

        @Override
        public boolean hasNext() {
            boolean currentHasNext;
            while (!(currentHasNext = current.hasNext()) && iterators.hasNext()) {
                current = iterators.next();
            }
            return currentHasNext;
        }

        @Override
        public E next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            removeFrom = current;
            return current.next();
        }

        @Override
        public void remove() {
            if (removeFrom == null) {
                throw new IllegalStateException();
            }
            removeFrom.remove();
            removeFrom = null;
        }

    }

    /**
     *
     * @param  The original type
     * @param  The result type
     */
    static class TransformingIterator implements Iterator {

        final Iterator iterator;
        final Function function;

        TransformingIterator(Iterator iterator, Function function) {
            this.iterator = iterator;
            this.function = function;
        }

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

        @Override
        public final R next() {
            return function.apply(iterator.next());
        }

        @Override
        public final void remove() {
            iterator.remove();
        }
    }

    /**
     * Abstract iterator implementation that tracks current index. This implementation is useful for collection implementations
     * with well-known size and random access to elements where its {@link IndexIterator#getElement(int)} may use a switch/case
     * construct to return the corresponding element.
     *
     * @author Jozef Hartinger
     *
     * @param  the element type
     */
    abstract static class IndexIterator implements ListIterator {

        private int position;
        private final int size;

        IndexIterator(int size, int position) {
            this.size = size;
            this.position = position;
        }

        IndexIterator(int size) {
            this(size, 0);
        }

        @Override
        public boolean hasNext() {
            return position < size;
        }

        @Override
        public E next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return getElement(position++);
        }

        @Override
        public boolean hasPrevious() {
            return position > 0;
        }

        @Override
        public E previous() {
            if (!hasPrevious()) {
                throw new NoSuchElementException();
            }
            return getElement(--position);
        }

        @Override
        public int nextIndex() {
            return position;
        }

        @Override
        public int previousIndex() {
            return position -1;
        }

        /**
         * Returns the element identified by the given index.
         * @param index the given index
         * @return element identified by the given index
         */
        abstract E getElement(int index);

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

        @Override
        public void set(E e) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void add(E e) {
            throw new UnsupportedOperationException();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy