intermediate operations or terminal operations.java.util.stream.Stream interface from a data source (collection, array, set of elements).
The Stream interface represents a sequence of elements supporting sequential and parallel aggregate operations.
import java.util.Arrays;
import java.util.stream.Stream;
// Creates a stream from a set of values.
Stream<Integer> integerStream1 = Stream.of(1, 2, 3);
// Creates a stream from an array.
Integer[] values = {1, 2, 3};
Stream<Integer> integerStream2 = Stream.of(values);
Stream<Integer> integerStream3 = Arrays.stream(values);
// Creates a stream from a list.
Stream<Integer> integerStream4 = Arrays.asList(values).stream();
Stream interface.import java.util.stream.Stream; Stream<Integer> integerStream1 = Stream.of(1, 2, 3); // The intermediate operation "filter" transforms a stream into another stream Stream<Integer> integerStream2 = integerStream1.filter(i -> i % 2 == 0); // The intermediate operation "map" transforms a stream into another stream Stream<String> stringStream = integerStream2.map(i -> String.valueOf(i));
collect, reduce, and count, as well as short-circuiting operations like findFirst and anyMatch.import java.util.stream.Stream; // The terminal operation "count" produces a result long count = Stream.of(1, 2, 3).count(); // The terminal operation "forEach" produces a side effect Stream.of(1, 2, 3).forEach(System.out::println);
import java.util.stream.Stream; // filter and limit are intermediate operations; they won't be applied yet Stream<Integer> integerStream1 = Stream.of(1, 2, 3, 4, 5, 6).filter(i -> i % 2 == 0).limit(2); // forEach is a terminal operation; all intermediate operations along with the terminal operation will now be applied integerStream1.forEach(System.out::println);
Stream instance, that stream is closed and cannot be reused.Stream instance
after it has already been operated upon or closed, an exception will be thrown:"IllegalStateException: stream has already been operated upon or closed".import java.util.stream.Stream; Stream<Integer> integerStream1 = Stream.of(1, 2, 3); // OK: first operation on "integerStream1" Stream<Integer> integerStream2 = integerStream1.filter(i -> i % 2 == 0); // Runtime Exception: IllegalStateException - stream has already been operated upon or closed Stream<Integer> integerStream3 = integerStream1.filter(i -> i % 2 == 0); // Runtime Exception: IllegalStateException - stream has already been operated upon or closed long count = integerStream1.count(); // OK: first operation on "integerStream2" System.out.println(integerStream2.count()); // Runtime Exception: IllegalStateException - stream has already been operated upon or closed System.out.println(integerStream2.count());
import java.util.Arrays;
Integer[] values = {1, 2, 3};
// stream returns a sequential Stream
Arrays.stream(values).forEach(System.out::println);
Arrays.asList(values).stream().forEach(System.out::println);
// parallel/parallelStream returns a possibly parallel Stream
Arrays.stream(values).parallel().forEach(System.out::println);
Arrays.asList(values).parallelStream().forEach(System.out::println);
collect (terminal operation)collect method.<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Stream; Stream<Integer> integerStream = Stream.of(1, 2, 3); Supplier<StringBuilder> supplier = StringBuilder::new; BiConsumer<StringBuilder, ? super Integer> accumulator = StringBuilder::append; BiConsumer<StringBuilder, StringBuilder> combiner = StringBuilder::append; StringBuilder stringBuilder = integerStream.collect(supplier, accumulator, combiner);
<R, A> R collect(Collector<? super T, A, R> collector);import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; Stream<Integer> integerStream = Stream.of(1, 2, 3); // Collectors.toList() returns a Collector that accumulates elements into a List List<Integer> list = integerStream.collect(Collectors.toList());
map (intermediate operation)map applies the given function to each element of the stream and produces a new stream containing the results.<R> Stream<R> map(Function<? super T, ? extends R> mapper);import java.util.stream.Stream; Stream<Integer> intStream = Stream.of(1, 2, 3); Stream<String> stringStream = intStream.map(String::valueOf); stringStream.forEach(System.out::println);
filter (intermediate operation)filter applies the given predicate to filter elements of the stream, retaining only those that match.Stream<T> filter(Predicate<? super T> predicate);import java.util.stream.Stream; Stream<Integer> intStream1 = Stream.of(1, 2, 3, 4, 5); Stream<Integer> intStream2 = intStream1.filter(i -> i % 2 == 0); intStream2.forEach(System.out::println);
findFirst / findAny (terminal operations)findFirst returns the first element of the stream wrapped in an Optional.Optional<T> findFirst();findAny returns any element of the stream wrapped in an Optional, possibly the first but not guaranteed.Optional<T> findAny();
import java.util.Optional;
import java.util.stream.Stream;
Optional<Integer> firstValue = Stream.of(1, 2, 3).findFirst();
if (firstValue.isPresent()) {
System.out.println(firstValue.get());
}
Optional<Integer> anyValue = Stream.of(1, 2, 3).findAny();
anyValue.ifPresent(System.out::println);
anyMatch / allMatch / noneMatch (terminal operations)anyMatch returns true if any element matches the predicate.boolean anyMatch(Predicate<? super T> predicate);allMatch returns true if all elements match the predicate.boolean allMatch(Predicate<? super T> predicate);noneMatch returns true if no elements match the predicate.boolean noneMatch(Predicate<? super T> predicate);import java.util.stream.Stream; // anyMatch boolean anyMatch = Stream.of(1, 2, 3).anyMatch(i -> i % 2 == 1); System.out.println(anyMatch); // true // allMatch boolean allMatch = Stream.of(1, 2, 3).allMatch(i -> i % 2 == 1); System.out.println(allMatch); // false // noneMatch boolean noneMatch = Stream.of(1, 2, 3).noneMatch(i -> i % 2 == 1); System.out.println(noneMatch); // false
reduce (terminal operation)reduce performs a reduction on the elements of the stream using an accumulator function and returns an Optional or a single value.Optional<T> reduce(BinaryOperator<T> accumulator);T reduce(T identity, BinaryOperator<T> accumulator);import java.util.Optional; import java.util.stream.Stream; // Sum using reduce with Optional Optional<Integer> sum1 = Stream.of(1, 2, 3, 4, 5).reduce((a, b) -> a + b); sum1.ifPresent(System.out::println); // 15 // Sum using reduce with identity int sum2 = Stream.of(1, 2, 3, 4, 5).reduce(0, (a, b) -> a + b); System.out.println(sum2); // 15
limit / skip (intermediate operations)limit returns a stream with at most the specified number of elements.Stream<T> limit(long maxSize);skip returns a stream with the first specified number of elements discarded.Stream<T> skip(long n);import java.util.stream.Stream; // limit - only first 3 elements Stream.of(1, 2, 3, 4, 5).limit(3).forEach(System.out::println); // 1, 2, 3 // skip - first 2 elements Stream.of(1, 2, 3, 4, 5).skip(2).forEach(System.out::println); // 3, 4, 5 // skip and limit Stream.of(1, 2, 3, 4, 5).skip(2).limit(3).forEach(System.out::println); // 3, 4, 5
distinct (intermediate operation)distinct returns a stream with duplicate elements removed based on their equals() method.Stream<T> distinct();import java.util.stream.Stream; Stream.of(1, 1, 2, 3, 4, 4, 5).distinct().forEach(System.out::println); // 1, 2, 3, 4, 5
sorted (intermediate operation)sorted returns a stream with elements sorted in natural order or according to a provided Comparator.Stream<T> sorted();Stream<T> sorted(Comparator<? super T> comparator);import java.util.Comparator; import java.util.stream.Stream; // Natural order sorting Stream.of(1, 3, 2, 5, 4, 1).sorted().forEach(System.out::println); // 1, 1, 2, 3, 4, 5 // Custom comparator - reverse order Stream.of(1, 3, 2, 5, 4, 1).sorted(Comparator.reverseOrder()).forEach(System.out::println); // 5, 4, 3, 2, 1, 1
java.util.stream" package:BaseStream: BaseStream<T, S extends BaseStream<T, S>> extends AutoCloseable
public interface BaseStream<T, S extends BaseStream<T, S>> extends AutoCloseable {
Iterator<T> iterator();
Spliterator<T> spliterator();
boolean isParallel();
S sequential();
S parallel();
S unordered();
S onClose(Runnable closeHandler);
@Override
void close();
}
Stream: Stream<T> extends BaseStream<T, Stream<T>>BaseStream" interface for object references.
It defines several methods for transformation, filtering, aggregation, etc. (filter, map, reduce, distinct, count, ...).
public interface Stream<T> extends BaseStream<T, Stream<T>> {
// Filtering operations (intermediate operations)
Stream<T> filter(Predicate<? super T> predicate);
// Mapping operations (intermediate operations)
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
// count operations (terminal operations)
long count();
// reduce operations (terminal operations)
Optional<T> reduce(BinaryOperator<T> accumulator);
// ... other methods
}
IntStream: IntStream extends BaseStream<Integer, IntStream>BaseStream" interface for primitive int values.
It defines several methods for transformation, filtering, aggregation, etc. (filter, map, reduce, distinct, count, sum, average, ...).
public interface IntStream extends BaseStream<Integer, IntStream> {
// Filtering operations (intermediate operations)
IntStream filter(IntPredicate predicate);
// Mapping operations (intermediate operations)
IntStream map(IntUnaryOperator mapper);
// sum operations (terminal operations)
int sum();
// average operations (terminal operations)
OptionalDouble average();
// ... other methods
}
LongStream: LongStream extends BaseStream<Long, LongStream>BaseStream" interface for primitive long values.
It defines several methods for transformation, filtering, aggregation, etc. (filter, map, reduce, distinct, count, sum, average, ...).
public interface LongStream extends BaseStream<Long, LongStream> {
// Filtering operations (intermediate operations)
LongStream filter(LongPredicate predicate);
// Mapping operations (intermediate operations)
LongStream map(LongUnaryOperator mapper);
// sum operations (terminal operations)
long sum();
// average operations (terminal operations)
OptionalDouble average();
// ... other methods
}
DoubleStream: DoubleStream extends BaseStream<Double, DoubleStream>BaseStream" interface for primitive double values.
It defines several methods for transformation, filtering, aggregation, etc. (filter, map, reduce, distinct, count, sum, average, ...).
public interface DoubleStream extends BaseStream<Double, DoubleStream> {
// Filtering operations (intermediate operations)
DoubleStream filter(DoublePredicate predicate);
// Mapping operations (intermediate operations)
DoubleStream map(DoubleUnaryOperator mapper);
// sum operations (terminal operations)
double sum();
// average operations (terminal operations)
OptionalDouble average();
// ... other methods
}