Created
February 16, 2014 22:58
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.keepsafe.services.manifest.collect; | |
import com.google.common.base.Function; | |
import com.google.common.base.Predicate; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.NoSuchElementException; | |
import java.util.Set; | |
/** | |
* Represents a lazy, read-once stream of elements which may be filtered, | |
* transformed to different types, and consumed. | |
* | |
* <p>Streams differ from iterables in that where iterables provide sequential | |
* access to a collection, Streams are intended to be queried and transformed | |
* declaratively.</p> | |
* | |
* <p>Streams exist in two states - terminal and non-terminal. When a stream | |
* is non-terminal, query operations and transformations may be applied. When | |
* a termination operation is invoked, the stream is placed in a terminal | |
* state.</p> | |
* | |
* <p>>Non-terminal operations are those that do not immediately consume | |
* elements from the source stream, i.e. {@link Stream#map(Function)}, | |
* {@link Stream#filter(Predicate)}, etc.</p> | |
* | |
* <p>Terminal operations are those that consume elements, such as | |
* {@link Stream#reduce(Object, Reducer)} and {@link Stream#single()}.</p> | |
* | |
* <p>This API is heavily cribbed from the Java 8 specification, with a healthy | |
* dose of LINQ for good measure. The implementation is entirely original, if | |
* not exactly novel.</p> | |
* | |
* @param <T> the type of element in the stream. | |
* | |
* @author ben | |
*/ | |
public interface Stream<T> extends Iterable<T> { | |
/** | |
* Projects the current stream into a stream of type {@link R}. | |
* @param mapper a function mapping elements of type {@link T} to type {@link R}. | |
* @param <R> the type of element in the projected stream. | |
* @return the projected stream. | |
*/ | |
<R> Stream<R> map(Function<T, R> mapper); | |
/** | |
* Filters a stream such that only elements satisfying the given | |
* {@code predicate} are included. | |
* | |
* @param predicate the predicate with which to filter the stream | |
* @return the filtered stream | |
*/ | |
Stream<T> filter(Predicate<T> predicate); | |
/** | |
* Projects each element of the stream to a collection of type {@link R}, | |
* and returns a stream of each such collection's elements in succession. | |
* | |
* <code> | |
* Stream<String> strs = Streams.of("foo", "bar"); | |
* Function<String, Iterable<Char>> mapper = str -> str.getChars(); | |
* | |
* strs.flatMap(mapper); // yields {'f', 'o', 'o', 'b', 'a', 'r'} | |
* </code> | |
* @param mapper | |
* @param <R> | |
* @return | |
*/ | |
<R> Stream<R> flatMap(Function<T, Iterable<R>> mapper); | |
/** | |
* Takes the first N items of the stream | |
* @param count | |
* @return | |
*/ | |
Stream<T> take(int count); | |
/** | |
* Casts each element of the stream to the given type {@link R}. | |
* | |
* <p>Use this at your own risk - due to type erasure, this is entirely | |
* unchecked and correctness is not enforced at compile-time.</p> | |
* | |
* @param <R> the type to cast each element | |
* @return a stream of type {@link R} | |
*/ | |
<R> Stream<R> cast(); | |
/** | |
* Extract and return the single element contained in the stream. | |
* | |
* <p>This is a terminal operation.</p> | |
* | |
* @return the single element in the stream. | |
* @throws NoSuchElementException when the stream does not contain exactly | |
* one element. | |
*/ | |
T single() throws NoSuchElementException; | |
/** | |
* Returns the first element in the stream, or {@code null} if the stream | |
* is empty. | |
* | |
* <p>This is a terminal operation.</p> | |
* | |
* @return The first element, or {@code null}. | |
*/ | |
T firstOrDefault(); | |
/** | |
* Gathers the contents of the stream into a {@link List} and returns it. | |
* | |
* <p>This is a terminal operation.</p> | |
* | |
* @return the constructed list. | |
*/ | |
List<T> toList(); | |
/** | |
* Projects a stream into a {@link Map} based on the given key and value | |
* projectors. | |
* | |
* <p>This is a terminal operation.</p> | |
* @param keySelector a function that, given an element, will produce a | |
* map key. | |
* @param valueSelector a function that, given an element, will produce a | |
* map value. | |
* @param <K> the type of the map key | |
* @param <V> the type of the map value | |
* @return the constructed map. | |
*/ | |
<K, V> Map<K, V> toMap(Function<T, K> keySelector, Function<T, V> valueSelector); | |
Set<T> toSet(); | |
<R> Set<R> toSet(Function<T, R> mapper); | |
/** | |
* Applies a reducing operation to the stream, transforming its elements | |
* using the supplied {@link Reducer} for each element and returning the | |
* result. | |
* | |
* <p>This is a terminal operation.</p> | |
* | |
* @param seed The initial accumulator value | |
* @param reducer The reducing operation to apply | |
* @return the final accumulator value | |
*/ | |
<A> A reduce(A seed, Reducer<A, T> reducer); | |
/** | |
* Append the given stream to the end of this stream. | |
* @param stream the stream to append | |
* @return the combined stream | |
*/ | |
Stream<T> concat(Stream<T> stream); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment