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

org.d2ab.sequence.EntrySequence Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
/*
 * Copyright 2015 Daniel Skogquist Åborg
 *
 * 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.d2ab.sequence;

import org.d2ab.function.QuaternaryFunction;
import org.d2ab.iterable.ChainingIterable;
import org.d2ab.iterable.Iterables;
import org.d2ab.iterator.*;
import org.d2ab.util.Entries;

import javax.annotation.Nullable;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.*;
import java.util.stream.Collector;
import java.util.stream.Stream;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyIterator;

/**
 * An {@link Iterable} sequence of elements with {@link Stream}-like operations for refining, transforming and
 * collating the list of elements.
 */
@FunctionalInterface
public interface EntrySequence extends Iterable> {
	static  EntrySequence of(Entry item) {
		return from(Collections.singleton(item));
	}

	@SafeVarargs
	static  EntrySequence of(Entry... items) {
		return from(asList(items));
	}

	static  EntrySequence ofEntry(K left, V right) {
		return of(Entries.of(left, right));
	}

	@SafeVarargs
	static  EntrySequence from(Iterable>... iterables) {
		return () -> new ChainingIterator<>(iterables);
	}

	static  EntrySequence from(Iterable> iterable) {
		return iterable::iterator;
	}

	static  EntrySequence empty() {
		return from(emptyIterator());
	}

	static  EntrySequence from(Iterator> iterator) {
		return () -> iterator;
	}

	static  EntrySequence from(Stream> stream) {
		return stream::iterator;
	}

	static  EntrySequence from(Supplier>> iteratorSupplier) {
		return iteratorSupplier::get;
	}

	static  EntrySequence recurse(@Nullable K keySeed,
	                                          @Nullable V valueSeed,
	                                          BiFunction> op) {
		return () -> new RecursiveIterator<>(Entries.of(keySeed, valueSeed), Entries.asUnaryOperator(op));
	}

	static  EntrySequence recurse(@Nullable K keySeed,
	                                                    @Nullable V valueSeed,
	                                                    BiFunction> f,
	                                                    BiFunction> g) {
		return () -> new RecursiveIterator<>(f.apply(keySeed, valueSeed), Entries.asUnaryOperator(f, g));
	}

	static  EntrySequence from(Map map) {
		return map.entrySet()::iterator;
	}

	default  EntrySequence map(BiFunction> mapper) {
		return map(Entries.asFunction(mapper));
	}

	default  EntrySequence map(Function, ? extends Entry> mapper) {
		return () -> new MappingIterator<>(mapper).backedBy(iterator());
	}

	default  EntrySequence map(Function keyMapper,
	                                           Function valueMapper) {
		return map(Entries.asFunction(keyMapper, valueMapper));
	}

	default EntrySequence skip(int skip) {
		return () -> new SkippingIterator>(skip).backedBy(iterator());
	}

	default EntrySequence limit(int limit) {
		return () -> new LimitingIterator>(limit).backedBy(iterator());
	}

	@SuppressWarnings("unchecked")
	default EntrySequence then(EntrySequence then) {
		return () -> new ChainingIterator<>(this, then);
	}

	default EntrySequence filter(BiPredicate predicate) {
		return filter(Entries.asPredicate(predicate));
	}

	default EntrySequence filter(Predicate> predicate) {
		return () -> new FilteringIterator<>(predicate).backedBy(iterator());
	}

	default  EntrySequence flatMap(BiFunction>>
			                                               mapper) {
		return flatMap(Entries.asFunction(mapper));
	}

	default  EntrySequence flatMap(Function, ? extends Iterable>>
			                                               mapper) {
		ChainingIterable> result = new ChainingIterable<>();
		toSequence(mapper).forEach(result::append);
		return result::iterator;
	}

	default EntrySequence until(Entry terminal) {
		return () -> new ExclusiveTerminalIterator<>(terminal).backedBy(iterator());
	}

	default EntrySequence endingAt(Entry terminal) {
		return () -> new InclusiveTerminalIterator<>(terminal).backedBy(iterator());
	}

	default EntrySequence until(K key, V value) {
		return until(Entries.of(key, value));
	}

	default EntrySequence endingAt(K key, V value) {
		return endingAt(Entries.of(key, value));
	}

	default EntrySequence until(BiPredicate terminal) {
		return until(Entries.asPredicate(terminal));
	}

	default EntrySequence endingAt(BiPredicate terminal) {
		return endingAt(Entries.asPredicate(terminal));
	}

	default EntrySequence until(Predicate> terminal) {
		return () -> new ExclusiveTerminalIterator<>(terminal).backedBy(iterator());
	}

	default EntrySequence endingAt(Predicate> terminal) {
		return () -> new InclusiveTerminalIterator<>(terminal).backedBy(iterator());
	}

	default Entry[] toArray() {
		return toArray(Entry[]::new);
	}

	default Entry[] toArray(IntFunction[]> constructor) {
		List list = toList();
		@SuppressWarnings("unchecked")
		Entry[] array = (Entry[]) list.toArray(constructor.apply(list.size()));
		return array;
	}

	default List> toList() {
		return toList(ArrayList::new);
	}

	default List> toList(Supplier>> constructor) {
		return toCollection(constructor);
	}

	default Set> toSet() {
		return toSet(HashSet::new);
	}

	default >> S toSet(Supplier constructor) {
		return toCollection(constructor);
	}

	default SortedSet> toSortedSet() {
		return toSet(TreeSet::new);
	}

	default Map toMap() {
		return toMap(HashMap::new);
	}

	default > M toMap(Supplier constructor) {
		M result = constructor.get();
		forEach(each -> Entries.put(result, each));
		return result;
	}

	default SortedMap toSortedMap() {
		return toMap(TreeMap::new);
	}

	default >> C toCollection(Supplier constructor) {
		return collect(constructor, Collection::add);
	}

	default  C collect(Supplier constructor, BiConsumer> adder) {
		C result = constructor.get();
		forEach(each -> adder.accept(result, each));
		return result;
	}

	default  S collect(Collector, R, S> collector) {
		R result = collector.supplier().get();
		BiConsumer> accumulator = collector.accumulator();
		forEach(each -> accumulator.accept(result, each));
		return collector.finisher().apply(result);
	}

	default String join(String delimiter) {
		return join("", delimiter, "");
	}

	default String join(String prefix, String delimiter, String suffix) {
		StringBuilder result = new StringBuilder();
		result.append(prefix);
		boolean first = true;
		for (Entry each : this) {
			if (first)
				first = false;
			else
				result.append(delimiter);
			result.append(each);
		}
		result.append(suffix);
		return result.toString();
	}

	default Optional> reduce(BinaryOperator> operator) {
		Iterator> iterator = iterator();
		if (!iterator.hasNext())
			return Optional.empty();

		Entry result = reduce(iterator.next(), operator, iterator);
		return Optional.of(result);
	}

	default Optional> reduce(QuaternaryFunction> operator) {
		Iterator> iterator = iterator();
		if (!iterator.hasNext())
			return Optional.empty();

		Entry result = reduce(iterator.next(), Entries.asBinaryOperator(operator), iterator);
		return Optional.of(result);
	}

	default Entry reduce(Entry identity, BinaryOperator> operator) {
		return reduce(identity, operator, iterator());
	}

	default Entry reduce(K key, V value, QuaternaryFunction> operator) {
		return reduce(Entries.of(key, value), Entries.asBinaryOperator(operator), iterator());
	}

	default Entry reduce(Entry identity,
	                           BinaryOperator> operator,
	                           Iterator> iterator) {
		Entry result = identity;
		while (iterator.hasNext())
			result = operator.apply(result, iterator.next());
		return result;
	}

	default Optional> first() {
		Iterator> iterator = iterator();
		if (!iterator.hasNext())
			return Optional.empty();

		return Optional.of(iterator.next());
	}

	default Optional> second() {
		Iterator> iterator = iterator();

		Iterators.skip(iterator);
		if (!iterator.hasNext())
			return Optional.empty();

		return Optional.of(iterator.next());
	}

	default Optional> third() {
		Iterator> iterator = iterator();

		Iterators.skip(iterator, 2);
		if (!iterator.hasNext())
			return Optional.empty();

		return Optional.of(iterator.next());
	}

	default Optional> last() {
		Iterator> iterator = iterator();
		if (!iterator.hasNext())
			return Optional.empty();

		Entry last;
		do {
			last = iterator.next();
		} while (iterator.hasNext());

		return Optional.of(last);
	}

	default Sequence>> partition(int window) {
		return () -> new PartitioningIterator>(window).backedBy(iterator());
	}

	default EntrySequence step(int step) {
		return () -> new SteppingIterator>(step).backedBy(iterator());
	}

	default EntrySequence distinct() {
		return () -> new DistinctIterator>().backedBy(iterator());
	}

	default EntrySequence sorted() {
		return () -> new SortingIterator>().backedBy(iterator());
	}

	default EntrySequence sorted(Comparator> comparator) {
		return () -> new SortingIterator>(comparator).backedBy(iterator());
	}

	default Optional> min(Comparator> comparator) {
		return reduce(BinaryOperator.minBy(comparator));
	}

	default Optional> max(Comparator> comparator) {
		return reduce(BinaryOperator.maxBy(comparator));
	}

	default int count() {
		int count = 0;
		for (Entry ignored : this)
			count++;
		return count;
	}

	default boolean all(BiPredicate biPredicate) {
		Predicate> predicate = Entries.asPredicate(biPredicate);
		for (Entry each : this)
			if (!predicate.test(each))
				return false;
		return true;
	}

	default boolean none(BiPredicate predicate) {
		return !any(predicate);
	}

	default boolean any(BiPredicate biPredicate) {
		Predicate> predicate = Entries.asPredicate(biPredicate);
		for (Entry each : this)
			if (predicate.test(each))
				return true;
		return false;
	}

	default EntrySequence peek(BiConsumer action) {
		Consumer> consumer = Entries.asConsumer(action);
		return () -> new PeekingIterator<>(consumer).backedBy(iterator());
	}

	default EntrySequence append(Iterator> iterator) {
		return append(Iterables.from(iterator));
	}

	default EntrySequence append(Iterable> that) {
		@SuppressWarnings("unchecked")
		Iterable> chainingSequence = new ChainingIterable<>(this, that);
		return chainingSequence::iterator;
	}

	@SuppressWarnings("unchecked")
	default EntrySequence append(Entry... entries) {
		return append(Iterables.from(entries));
	}

	@SuppressWarnings("unchecked")
	default EntrySequence appendEntry(K key, V value) {
		return append(Entries.of(key, value));
	}

	default EntrySequence append(Stream> stream) {
		return append(Iterables.from(stream));
	}

	default Sequence> toSequence() {
		return Sequence.from(this);
	}

	default  Sequence toSequence(BiFunction mapper) {
		return toSequence(Entries.asFunction(mapper));
	}

	default  Sequence toSequence(Function, ? extends T> mapper) {
		return () -> new MappingIterator<>(mapper).backedBy(iterator());
	}

	default EntrySequence repeat() {
		return () -> new RepeatingIterator<>(this, -1);
	}

	default EntrySequence repeat(long times) {
		return () -> new RepeatingIterator<>(this, times);
	}

	default EntrySequence reverse() {
		return () -> new ReverseIterator>().backedBy(iterator());
	}

	default EntrySequence shuffle() {
		List> list = toList();
		Collections.shuffle(list);
		return from(list);
	}

	default EntrySequence shuffle(Random md) {
		List> list = toList();
		Collections.shuffle(list, md);
		return from(list);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy