net.sf.staccatocommons.collections.stream.Streams Maven / Gradle / Ivy
/**
* Copyright (c) 2011, The Staccato-Commons Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* 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 Lesser General Public License for more details.
*/
package net.sf.staccatocommons.collections.stream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import net.sf.staccatocommons.collections.restrictions.Projection;
import net.sf.staccatocommons.collections.restrictions.Repeatable;
import net.sf.staccatocommons.collections.stream.internal.CharSequenceStream;
import net.sf.staccatocommons.collections.stream.internal.CollectionStream;
import net.sf.staccatocommons.collections.stream.internal.DequeStream;
import net.sf.staccatocommons.collections.stream.internal.EmptyStream;
import net.sf.staccatocommons.collections.stream.internal.IterableStream;
import net.sf.staccatocommons.collections.stream.internal.IteratorStream;
import net.sf.staccatocommons.collections.stream.internal.ListStream;
import net.sf.staccatocommons.collections.stream.internal.SingleStream;
import net.sf.staccatocommons.collections.stream.internal.algorithms.UndefinedStream;
import net.sf.staccatocommons.collections.stream.internal.algorithms.delayed.ConsStream;
import net.sf.staccatocommons.collections.stream.internal.algorithms.delayed.DelayedSingleStream;
import net.sf.staccatocommons.defs.Applicable;
import net.sf.staccatocommons.defs.Evaluable;
import net.sf.staccatocommons.defs.Thunk;
import net.sf.staccatocommons.iterators.EnumerationIterator;
import net.sf.staccatocommons.iterators.thriter.AbstractThriterator;
import net.sf.staccatocommons.iterators.thriter.NextThriterator;
import net.sf.staccatocommons.lang.predicate.Predicates;
import net.sf.staccatocommons.lang.sequence.Sequence;
import net.sf.staccatocommons.lang.sequence.StopConditions;
import net.sf.staccatocommons.lang.thunk.Thunks;
import net.sf.staccatocommons.restrictions.Conditionally;
import net.sf.staccatocommons.restrictions.Constant;
import net.sf.staccatocommons.restrictions.check.NonNull;
import net.sf.staccatocommons.restrictions.processing.IgnoreRestrictions;
/**
* Class methods for creating very simple {@link Stream}s wrapping existing
* classes from the Java collections framework, specifiying its elements and
*
* @author flbulgarelli
*/
public class Streams {
private Streams() {}
/**
* Creates a new {@link Stream} that retrieves elements from a head's thunk,
* and another {@link Iterable}, called tail.
*
* This operation is known and cons(tructing), and can be undone by
* sending {@link Stream#delayedDecons()} to the resulting Stream.
*
* The returned stream is {@link Repeatable} as long as the thunk's head value
* is always equal, and the tail is repeatable.
*
* @param
* @param head
* @param tail
* @return a new {@link Stream}
*/
@Projection
@Conditionally(Repeatable.class)
public static Stream cons(final Thunk head, @NonNull final Stream extends A> tail) {
return new ConsStream(head, (Stream) tail);
}
/**
* Creates a new {@link Stream} that retrieves elements from a head, and
* another {@link Iterable}, called tail.
*
* This operation is known and cons(tructing), and can be undone by
* sending {@link Stream#decons()} to the resulting Stream.
*
* * The returned stream is {@link Repeatable} as long as the tail is
* repeatable.
*
* @param
* @param head
* @param tail
* @return a new {@link Stream}
*/
@Projection
@Conditionally(Repeatable.class)
public static Stream cons(final A head, @NonNull final Stream extends A> tail) {
return new ConsStream(Thunks.constant(head), (Stream) tail);
}
/**
* Creates a new {@link Stream} that retrieves the elements from the given
* array. This stream permits efficient random access and grants repeatable
* iteration order.
*
* @param
* the element type
* @param elements
* the array that is Stream source
* @return a new stream that gets its elements from an array
*/
@Repeatable
@Projection
public static Stream cons(@NonNull A... elements) {
return from(Arrays.asList(elements));
}
/**
* Creates a one-element new Stream that will retrieve the thunk's value.
*
* This stream is {@link Repeatable} as long as the thunk's value is always
* equal.
*
* @param
* @param element
* @return a new
*
* @see Thunk#value()
*/
@Projection
@Repeatable
public static Stream cons(Thunk element) {
return new DelayedSingleStream(element);
}
/**
* Creates a new Stream that will retrieve just the given element
*
* @param
* @param element
* the single element the new {@link Stream} will retrieve
* @return a new {@link Stream}
*/
@Repeatable
@Projection
public static Stream cons(A element) {
return new SingleStream(element);
}
/**
* Creates a new infinite {@link Stream} that retrieves element from the
* sequence
* Sequence.from(start, generator, StopConditions.stopNever())
*
* @param
* @param seed
* the initial element of the sequence
* @param generator
* a function used to generated each element from the sequence after
* the initial element
* @return a new {@link Stream}
* @see Sequence#from(Object, Applicable, Evaluable)
*/
@Projection
@IgnoreRestrictions
public static Stream iterate(@NonNull A seed, @NonNull Applicable super A, ? extends A> generator) {
return from(Sequence.from(seed, generator, StopConditions.stopNever()));
}
/**
* Creates a new infinite {@link Stream} that retrieves element from the
* sequence
* Sequence.from(start, generator, StopConditions.stopNever())
*
* @param
* @param seed
* the initial element of the sequence
* @param generator
* a function used to generated each element from the sequence after
* the initial element
* @return a new {@link Stream}
* @see Sequence#from(Object, Applicable, Evaluable)
*/
@Projection
@IgnoreRestrictions
public static Stream iterateUntilNull(@NonNull A seed, @NonNull Applicable super A, ? extends A> generator) {
return from(Sequence.from(seed, generator, Predicates.null_()));
}
/**
* Creates a new {@link Stream} that retrieves element from the sequence
* Sequence.from(start, generator, stopCondition)
*
* @param
* @param start
* the initial element of the sequence
* @param generator
* a function used to generated each element from the sequence after
* the initial element
* @param stopCondition
* predicate is satisfied when sequencing should stop, that is, when
* the given element and subsequent should not be retrieved.
* @return a new {@link Stream}
* @see Sequence#from(Object, Applicable, Evaluable)
*/
@Projection
@IgnoreRestrictions
public static Stream iterate(@NonNull A start, @NonNull Applicable super A, ? extends A> generator,
@NonNull Evaluable stopCondition) {
return from(Sequence.from(start, generator, stopCondition));
}
/**
* Creates a new {@link Stream} that retrieves element from the sequence
* Sequence.from(start, stop)
*
* @param start
* the seed of the sequence
* @param stop
* the stop value
* @return a new {@link Stream}
*/
@Projection
public static Stream iterate(int start, int stop) {
return from(Sequence.fromTo(start, stop));
}
/**
* Answers an infinite Stream that indefinitely retrieves the given element.
*
* @param
* @param element
* @return a new {@link Stream} that repeats the given element
*/
@Projection
public static Stream repeat(final A element) {
return from(new AbstractThriterator() {
public boolean hasNext() {
return true;
}
public A next() {
return element;
}
public void advanceNext() throws NoSuchElementException {}
public A current() {
return element;
}
});
}
/**
* Answers an infinite Stream that indefinitely retrieves the given thunk's
* value.
*
* @param
* @param thunk
* the {@link Thunk} whose value to repeat
* @return a new {@link Stream}
*/
@Projection
public static Stream repeat(@NonNull final Thunk thunk) {
return from(new NextThriterator() {
public boolean hasNext() {
return true;
}
public A nextImpl() {
return thunk.value();
}
});
}
// private static Stream cycle(@NonNull A element) {
// //return iterate(element, Functions. identity());
// }
/**
* Create a new {@link Stream} that retrieves elements from the given
* Iterable.
*
* @param
* the element type
* @param iterable
* the {@link Iterable} to decorate
* @return the given iterable, if it is {@link Stream}, a new stream that
* wraps it, otherwise
*/
@Projection
@Conditionally(Repeatable.class)
public static Stream from(@NonNull Iterable extends A> iterable) {
return iterable instanceof Stream ? (Stream) iterable : new IterableStream(iterable);
}
/**
* Creates a new {@link Stream} that retrieves elements from the given
* iterator. The resulting stream can not be iterated more than once, thus it
* is inherently mutable
*
* @param
* @param iterator
* source of the the new {@link Stream}
* @return a new {@link Stream}
*/
@Projection
@IgnoreRestrictions
public static Stream from(@NonNull Iterator extends A> iterator) {
return new IteratorStream(iterator);
}
/**
* Creates a new {@link Stream} that retrieves elements from the given
* {@link Enumeration}. The resulting stream can not be iterated more than
* once, thus it is inherently mutable
*
* @param
* @param enumeration
* source of the new {@link Stream}
* @return a new {@link Stream}
*/
@Projection
public static Stream from(@NonNull Enumeration extends A> enumeration) {
return from(new EnumerationIterator(enumeration));
}
/**
* Creates a new {@link Stream} that retrieves character elements from the
* given charSequence
*
* @param charSequence
* source of the of characters of the new Stream
* @return a new {@link Stream}
*/
@Repeatable
@Projection
public static Stream from(@NonNull final CharSequence charSequence) {
return new CharSequenceStream(charSequence);
}
/**
* Creates a new {@link Stream} that will retrieve elements from the given
* collection
*
* @param
* @param collection
* source of the new {@link Stream}
* @return a new {@link Stream}
*/
@Repeatable
@Projection
public static Stream from(@NonNull Collection extends A> collection) {
return new CollectionStream(collection);
}
/**
* Creates a new {@link Stream} that retrieves elements from a list. This
* streams grants repeatable iterator order and supports (not necessary
* efficient) random access by index.
*
* @param
* the element type
* @param list
* the source of the new {@link Stream}
* @return a new {@link Stream}
*/
@Repeatable
@Projection
public static Stream from(@NonNull List extends A> list) {
return new ListStream(list);
}
/**
* Creates a new {@link Stream} that retrieves elements from a {@link Deque}.
* This streams grants repeatable iterator order and supports (not necessary
* efficient) random access by index. This stream can be lazily reversed.
*
* @param
* the element type
* @param list
* the source of the new {@link Stream}
* @return a new {@link Stream}
*/
@NonNull
@Repeatable
@Projection
public static Stream from(@NonNull Deque extends A> list) {
return new DequeStream(list);
}
// public static Stream> from(Map iterable) {
// return new MapEntryStream(iterable);
// }
/**
* Answers a {@link Stream} that has no elements. This stream is immutable and
* singleton
*
* @param
* the element type
* @return a singleton empty {@link Stream}
*/
@Constant
@Repeatable
public static Stream empty() {
return EmptyStream.empty();
}
/**
* Answers a one element {@link Stream} that throws an exception when trying
* to access its element.
*
* @param
* @return a single elemtn Stream that throws an exception when accessing its
* only element
*/
@Constant
public static Stream undefined() {
return UndefinedStream.undefined();
}
/**
* Answers the Stream class, but preserving its element generic type. This
* method is mostly aimed to be used with Staccato-Commons-Lambda:
*
*
* lambda($(Streams.<User> type()).toList())
*
*
* @param
* @return (Class<Stream<A>>) Stream.class
*/
@Constant
public static Class> type() {
return (Class) Stream.class;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy