This example will show various code snippets to demonstrate stream terminal operations. Terminal operations produces a non-stream, result such as primitive value, a collection or no value at all. Terminal operations are typically preceded by intermediate operations which return another Stream which allows operations to be connected in a form of a query.
forEach
The Stream.forEach method will perform an action for each element in the stream. It is a simplified inline way to write a for loop. Below we will iterate over each element and will call System.our.println.
@Test
public void terminal_operation_foreach () {
Stream.of("Hello", "World").forEach(p -> System.out.println(p));
}
toArray
In similar examples, convert array to array list and convert collection to array, this snippet will convert a stream to an array by calling Stream.toArray
@Test
public void terminal_operation_toArray() {
Object[] objects = Stream.of(1, 2).toArray();
assertTrue(objects.length == 2);
}
reduce
Stream.reduce operations are commonly found in statistic operations such as long summary statistics and combine the stream elements into one using a BinaryOperator. In this snippet, we will find the sum of all elements in a stream.
@Test
public void terminal_operation_reduce() {
int sum = IntStream.of(1, 2, 3, 4).reduce(0, (a, b) -> a + b);
assertEquals(0, sum);
}
collect
The Stream.collect terminal operation will convert the stream into some other container such as a list. In the snippet below, we will convert a stream to a set. Other uses cases for the Stream.collect can be seen in convert a collection to a map, filter map by entries, stream group by, and joining strings.
@Test
public void terminal_operation_collect() {
Set<String> stringSet = Stream.of("some", "one", "some", "one")
.collect(Collectors.toSet());
assertThat(stringSet, contains(
"some", "one"));
assertTrue(stringSet.size() == 2);
}
min
Finding the minimum of a stream is another statistics type operation which can be performed by calling Stream.min. In this snippet we create an IntStream which is a specialized stream for handling primitive int and call the min. Finding the minimum of a stream is similar to finding the minimum of an array or minimum of a list.
@Test
public void terminal_operation_min() {
OptionalInt minimum = IntStream.of(1, 2, 3).min();
assertEquals(1, minimum.getAsInt());
}
max
Stream.max will find the maximum element of the stream according to a specified comparator. In the snippet below we will call Stream.mapToDouble which apply the given function Double::doubleValue to each element returning a DoubleStream. Finding the max element in a stream is similar to finding max value in a list and max value in an array.
@Test
public void terminal_operation_max() {
OptionalDouble max = Stream.of(1d, 2d, 3d)
.mapToDouble(Double::doubleValue).max();
assertEquals(1, max.getAsDouble(), 0);
}
count
Stream.count will find the number of elements in the stream. Counting the number of elements in a stream has similarities to counting the occurrences in a list, counting non empty strings in a collection and count words in file.
@Test
public void terminal_operation_count() {
long count = Stream.of("one").count();
assertEquals(1, count);
}
anymatch
Stream.anyMatch will find out whether at least one of the elements in the stream matches a given predicate. In this snippet, we will create a predicate from a lambda expression to check if the length of a string is greater than 5. Comparable examples can seen in guava iterables example and list contains any element.
@Test
public void terminal_operation_anymatch() {
boolean lengthOver5 = Stream.of("two", "three", "eighteen").anyMatch(
s -> s.length() > 5);
assertTrue(lengthOver5);
}
allMatch
Who doesn't like cookies! Stream.allMatch will check every element in the stream and find out if it matches the predicate. In the snippet below we will create a predicate with a lambda expression to check that each element in the list contains the character sequence "Cookies". Other related examples include list contains all and guava iterables all.
@Test
public void terminal_operation_allmatch() {
List<String> cookies = Lists.newArrayList("Peanut Butter Cookies",
"Oatmeal-Raisin Cookies", "Basic Chocolate Chip Cookies");
boolean containCookies = cookies.stream().allMatch(
p -> p.contains("Cookies"));
assertTrue(containCookies);
}
noneMatch
Just the opposite of Stream.anymatch, Stream.noneMatch will find if no elements in the stream match the specified predicate. In the snippet below, we will create a IntStream and then check each of the elements doesn't equal to 5. In addition to this snippet, the stream find and match example has a neat way of showing the noneMatch in relation to a hidden game object.
@Test
public void terminal_operation_nonematch() {
boolean noElementEqualTo5 = IntStream.of(1, 2, 3)
.noneMatch(p -> p == 5);
assertTrue(noElementEqualTo5);
}
findFirst
Stream.findFirst will find the first element in the stream which is resembles the same behavior as getting the first element in a list.
@Test
public void terminal_operation_findfirst() {
Optional<String> val = Stream.of("one", "two").findFirst();
assertEquals("one", val);
}
findAny
Similar to finding any element in array, Stream.findAny will find any element in a given stream.
@Test
public void terminal_operation_findany() {
Optional<String> val = Stream.of("one", "two").findAny();
assertEquals("one", val.get());
}