Easy Tutorial
❮ Java8 Base64 Java Examples ❯

Java 8 Stream

Java 8 New Features


Java 8 API introduces a new abstraction called Stream, which allows you to process data in a declarative way.

Stream provides a high-level abstraction for operating on Java collections and expressing them in a manner similar to SQL statements querying data from a database.

The Stream API can significantly enhance Java programmers' productivity, enabling them to write efficient, clean, and concise code.

This approach treats the collection of elements to be processed as a stream that flows through a pipeline, where it can be processed at various nodes such as filtering, sorting, and aggregation.

The element stream passes through intermediate operations in the pipeline and is finally processed by terminal operations to produce the results of the preceding operations.

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

The above process translates to the following Java code:

List<Integer> transactionsIds = 
widgets.stream()
             .filter(b -> b.getColor() == RED)
             .sorted((x,y) -> x.getWeight() - y.getWeight())
             .mapToInt(Widget::getWeight)
             .sum();

What is a Stream?

A Stream is a sequence of elements from a data source that supports aggregate operations.

Unlike previous Collection operations, Stream operations have two fundamental characteristics:


Generating Streams

In Java 8, the Collection interface has two methods to generate streams:


forEach

The Stream interface introduces a new method 'forEach' to iterate over each data in the stream. The following code snippet uses forEach to output 10 random numbers:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

map

The map method is used to map each element to its corresponding result. The following code snippet uses map to output the square of each element:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// Get the square of each element
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

filter

The filter method is used to filter out elements based on specified conditions. The following code snippet uses the filter method to filter out empty strings:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// Get the count of empty strings
long count = strings.stream().filter(string -> string.isEmpty()).count();

limit

The limit method is used to obtain a specified number of elements from the stream. The following code snippet uses the limit method to print out 10 data items:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

sorted

The sorted method is used to sort the stream. The following code snippet uses the sorted method to sort 10 random numbers:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

Parallel (parallel) processing

parallelStream is an alternative method for parallel processing of streams. The following example uses parallelStream to output the count of empty strings:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// Get the count of empty strings
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();

We can easily switch between sequential and parallel processing.


Collectors

The Collectors class implements many reduction operations, such as converting streams into collections and aggregating elements. Collectors can be used to return lists or strings:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

System.out.println("Filtered List: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);

Statistics

Additionally, collectors that produce statistical results are very useful. They are mainly used on basic types like int, double, long, and can be used to produce statistics like the following:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();

System.out.println("Highest number in List : " + stats.getMax());
System.out.println("Lowest number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());

Complete Stream Example

Place the following code into the Java8Tester.java file:

Java8Tester.java File

import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.Map;

public class Java8Tester {

public static void main(String args[]){ System.out.println("Using Java 7: ");

  // Count empty strings
  List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
  System.out.println("List: " +strings);
  long count = getCountEmptyStringUsingJava7(strings);

  System.out.println("Number of empty strings: " + count);
  count = getCountLength3UsingJava7(strings);

  System.out.println("Number of strings with length 3: " + count);

  // Remove empty strings
  List<String> filtered = deleteEmptyStringsUsingJava7(strings);
  System.out.println("Filtered list: " + filtered);

  // Remove empty strings and join them with a comma
  String mergedString = getMergedStringUsingJava7(strings,", ");
  System.out.println("Merged string: " + mergedString);
  List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

  // Get the square of each number
  List<Integer> squaresList = getSquares(numbers);
  System.out.println("List of squares: " + squaresList);
  List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);

  System.out.println("List: " +integers);
  System.out.println("Largest number in the list: " + getMax(integers));
  System.out.println("Smallest number in the list: " + getMin(integers));
  System.out.println("Sum of all numbers: " + getSum(integers));
  System.out.println("Average: " + getAverage(integers));
  System.out.println("Random numbers: ");

  // Output 10 random numbers
  Random random = new Random();

  for(int i=0; i < 10; i++){
     System.out.println(random.nextInt());
  }

  System.out.println("Using Java 8: ");
  System.out.println("List: " +strings);

  count = strings.stream().filter(string->string.isEmpty()).count();
  System.out.println("Number of empty strings: " + count);

  count = strings.stream().filter(string -> string.length() == 3).count();
  System.out.println("Number of strings with length 3: " + count);

  filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList());
  System.out.println("Filtered list: " + filtered);

  mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", "));
  System.out.println("Merged string: " + mergedString);

  squaresList = numbers.stream().map(i ->i*i).distinct().collect(Collectors.toList());
  System.out.println("List of squares: " + squaresList);

  IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics();
  System.out.println("Largest number in the list: " + stats.getMax());
  System.out.println("Smallest number in the list: " + stats.getMin());
  System.out.println("Sum of all numbers: " + stats.getSum());
  System.out.println("Average: " + stats.getAverage());

  System.out.println("Random numbers: ");
  random.ints().limit(10).forEach(System.out::println);

}

mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);

squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
System.out.println("Squares List: " + squaresList);
System.out.println("List: " + integers);

IntSummaryStatistics stats = integers.stream().mapToInt(x -> x).summaryStatistics();

System.out.println("Maximum number in List : " + stats.getMax());
System.out.println("Minimum number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());
System.out.println("Random Numbers: ");

random.ints().limit(10).sorted().forEach(System.out::println);

// Parallel processing
count = strings.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println("Count of empty strings: " + count);
}

private static int getCountEmptyStringUsingJava7(List<String> strings) {
int count = 0;

for (String string : strings) {

if (string.isEmpty()) {
count++;
}
}
return count;
}

private static int getCountLength3UsingJava7(List<String> strings) {
int count = 0;

for (String string : strings) {

if (string.length() == 3) {
count++;
}
}
return count;
}

private static List<String> deleteEmptyStringsUsingJava7(List<String> strings) {
List<String> filteredList = new ArrayList<String>();

for (String string : strings) {

if (!string.isEmpty()) {
filteredList.add(string);
}
}
return filteredList;
}

private static String getMergedStringUsingJava7(List<String> strings, String separator) {
StringBuilder stringBuilder = new StringBuilder();

for (String string : strings) {

if (!string.isEmpty()) {
public String mergeStrings(List<String> strings, String separator) {
    StringBuilder stringBuilder = new StringBuilder();
    for (String string : strings) {
        if (string != null && !string.isEmpty()) {
            stringBuilder.append(string);
            stringBuilder.append(separator);
        }
    }
    String mergedString = stringBuilder.toString();
    return mergedString.substring(0, mergedString.length() - 2);
}

private static List<Integer> getSquares(List<Integer> numbers) {
    List<Integer> squaresList = new ArrayList<>();
    for (Integer number : numbers) {
        Integer square = number * number;
        if (!squaresList.contains(square)) {
            squaresList.add(square);
        }
    }
    return squaresList;
}

private static int getMax(List<Integer> numbers) {
    int max = numbers.get(0);
    for (int i = 1; i < numbers.size(); i++) {
        Integer number = numbers.get(i);
        if (number > max) {
            max = number;
        }
    }
    return max;
}

private static int getMin(List<Integer> numbers) {
    int min = numbers.get(0);
    for (int i = 1; i < numbers.size(); i++) {
        Integer number = numbers.get(i);
        if (number < min) {
            min = number;
        }
    }
    return min;
}

private static int getSum(List<Integer> numbers) {
    int sum = numbers.get(0);
    for (int i = 1; i < numbers.size(); i++) {
        sum += numbers.get(i);
    }
    return sum;
}

private static int getAverage(List<Integer> numbers) {
    return getSum(numbers) / numbers.size();
}

Executing the above script, the output is:

$ javac Java8Tester.java 
$ java Java8Tester
Using Java 7: 
List: [abc, , bc, efg, abcd, , jkl]
Number of empty strings: 2
Number of strings with length 3: 3
Filtered list: [abc, bc, efg, abcd, jkl]
Merged string: abc, bc, efg, abcd, jkl
List of squares: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
Maximum number in the list: 19
Minimum number in the list: 1
Sum of all numbers: 85
Average: 9
Random numbers: 
-393170844
-963842252
447036679
-1043163142
-881079698
221586850
-1101570113
576190039
-1045184578
1647841045
Using Java 8: 
List: [abc, , bc, efg, abcd, , jkl]
Number of empty strings: 2
Number of strings with length 3: 3

Filtered list: [abc, bc, efg, abcd, jkl] Concatenated string: abc, bc, efg, abcd, jkl Squares list: [9, 4, 49, 25] List: [1, 2, 13, 4, 15, 6, 17, 8, 19] Largest number in the list: 19 Smallest number in the list: 1 Sum of all numbers: 85 Average: 9.444444444444445 Random numbers: -1743813696 -1301974944 -1299484995 -779981186 136544902 555792023 1243315896 1264920849 1472077135 1706423674 Number of empty strings: 2

❮ Java8 Base64 Java Examples ❯