com.thoughtworks.studios.journey.utils.IterableUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.thoughtworks.studios.journey.utils.IterableUtils.java

Source

/**
 * This file is part of journey-neo4j-plugin. journey-neo4j-plugin is a neo4j server extension that provides out-of-box action path analysis features on top of the graph database.
 *
 * Copyright 2015 ThoughtWorks, Inc. and Pengchao Wang
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.thoughtworks.studios.journey.utils;

import org.apache.commons.lang.NotImplementedException;
import org.neo4j.function.Function;
import org.neo4j.helpers.Predicate;
import org.neo4j.helpers.collection.Iterables;

import java.util.*;

import static org.neo4j.helpers.collection.Iterables.filter;

public class IterableUtils {

    public static <T> Iterable<T> compact(Iterable<T> iterable) {
        return filter(new Predicate<T>() {
            @Override
            public boolean accept(T item) {
                return item != null;
            }
        }, iterable);
    }

    public static <T> Iterable<T> toIterable(final Iterator<T> iterator) {
        return new Iterable<T>() {
            @Override
            public Iterator<T> iterator() {
                return iterator;
            }
        };
    }

    public static <FROM, TO> Iterable<TO> flatMap(final Function<FROM, Iterable<TO>> function,
            Iterable<FROM> from) {
        Iterator<TO> iterator = Iterables.flatMap(new Function<FROM, Iterator<TO>>() {
            @Override
            public Iterator<TO> apply(FROM o) {
                return function.apply(o).iterator();
            }
        }, from.iterator());
        return toIterable(iterator);
    }

    public static <T> RewindableIterator<T> rewindable(Iterator<T> original) {
        return new RewindableIterator<T>(original);
    }

    public static <T> Iterable<T> uniqueBy(final Function<T, Object> function, final Iterable<T> iterable) {
        return new Iterable<T>() {
            @Override
            public Iterator<T> iterator() {
                final Iterator<T> iterator = iterable.iterator();

                return new Iterator<T>() {
                    Set<Object> keys = new HashSet<>();
                    T nextItem;

                    @Override
                    public boolean hasNext() {
                        while (iterator.hasNext()) {
                            nextItem = iterator.next();
                            if (keys.add(function.apply(nextItem))) {
                                return true;
                            }
                        }

                        return false;
                    }

                    @Override
                    public T next() {
                        if (nextItem == null && !hasNext()) {
                            throw new NoSuchElementException();
                        }

                        return nextItem;
                    }

                    @Override
                    public void remove() {
                    }
                };
            }
        };
    }

    public static class RewindableIterator<T> implements Iterator<T> {
        private final ArrayList<T> visited;
        private Iterator<T> original;

        public RewindableIterator(Iterator<T> original) {
            this.original = original;
            this.visited = new ArrayList<T>();
        }

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

        @Override
        public T next() {
            T next = original.next();
            visited.add(next);
            return next;
        }

        @Override
        public void remove() {
            throw new NotImplementedException("can not remove in a rewindable iterator");
        }

        public Iterator<T> rewind() {
            return Iterables.concat(visited.iterator(), original);
        }

        public T lastVisited() {
            return visited.get(visited.size() - 1);
        }

        public Iterator<T> original() {
            return original;
        }
    }
}