Let's talk about Java 8 Stream features

Posted by jesse_james on Thu, 16 May 2019 13:47:26 +0200

The Java 8 API adds a new abstraction called Stream, which allows you to process data in a declarative manner.

Stream provides a high-order abstraction of Java set operations and expressions using an intuitive way similar to querying data from a database with SQL statements.

Stream API can greatly improve the productivity of Java programmers, allowing them to write efficient, clean and concise code.

This style considers the set of elements to be processed as a stream, which travels through the pipeline and can be processed at the nodes of the pipeline, such as filtering, sorting, aggregation, etc.

Element flow is processed by intermediate operation in the pipeline, and the result of the previous treatment is obtained by terminal operation.

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

The above process is converted to Java code as follows:

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

What is Stream?

Stream is an element queue from a data source and supports aggregation operations

  • The < strong = element queue > element is a specific type of object, forming a queue. Stream in Java does not store elements, but computes on demand.
  • Sources of data sources and streams. They can be collections, arrays, I/O channel s, generator s, etc.
  • Aggregation operations like SQL statements, such as filter, map, reduce, find, match, sort, etc.

Unlike previous Collection operations, Stream operations have two basic features:

  • Pipelining: Intermediate operations return the flow object itself. This allows multiple operations to be connected in series to form a pipeline, like a fluent style. This can optimize operations such as laziness and short-circuiting.
  • Internal iteration: In the past, iterations on collections were performed explicitly outside collections through Iterator or For-Each, which is called external iteration. Stream provides an internal iteration approach, implemented through Visitor mode.

Generating stream

In Java 8, the collection interface has two ways to generate streams:

  • stream() Creates a serial stream for a collection.
  • parallelStream() Creates parallel flows for collections.

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

forEach

Stream provides 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 corresponding square of the element:

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

filter

The filter method is used to filter out elements by setting conditions. The following code snippet filters out empty strings using the filter method:

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

limit

The limit method is used to get a specified number of streams. The following code snippet prints 10 pieces of data using the limit method:

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

sorted

The sorted method is used to sort convections. The following code snippets use the sorted method to sort the 10 random numbers output:

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

parallel program

Parallel Stream is an alternative to stream parallel processing. For the following example, we use parallelStream to output the number of empty strings:

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

We can easily run in sequence and switch directly in parallel.

Collectors

The Collectors class implements many reduction operations, such as transforming streams into collection and aggregation 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("Filter list: " + filtered);

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

Statistics

In addition, some collectors that produce statistical results are also very useful. They are mainly used for basic types such as int, double, long, etc. They can be used to produce statistical results similar to the following.

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

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

System.out.println("The largest number in the list : " + stats.getMax());

System.out.println("The smallest number in the list : " + stats.getMin());

System.out.println("The sum of all numbers : " + stats.getSum());

System.out.println("Average : " + stats.getAverage());

A complete example of Stream

Put the following code into the Java8Tester.java file:

Java8Tester.java file

package org.java.base.stream;
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("Use Java 7: ");

// Compute 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 characters is: " + count);
count = getCountLength3UsingJava7(strings);

System.out.println("The number of strings with a length of 3 is: " + count);

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

// Delete empty strings and merge them with commas
String mergedString = getMergedStringUsingJava7(strings,", ");
System.out.println("Merge strings: " + mergedString);
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

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

System.out.println("list: " +integers);
System.out.println("The largest number in the list : " + getMax(integers));
System.out.println("The smallest number in the list : " + getMin(integers));
System.out.println("The sum of all numbers : " + getSum(integers));
System.out.println("Average : " + getAverage(integers));
System.out.println("random number: ");

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

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

System.out.println("Use Java 8: ");
System.out.println("list: " +strings);

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

count = strings.stream().filter(string -> string.length() == 3).count();
System.out.println("The number of strings with a length of 3 is: " + 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("Merge strings: " + 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("The largest number in the list : " + stats.getMax());
System.out.println("The smallest number in the list : " + stats.getMin());
System.out.println("The sum of all numbers : " + stats.getSum());
System.out.println("Average : " + stats.getAverage());
System.out.println("random number: ");

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

// parallel processing
count = strings.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println("Number of empty strings is: " + 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()){
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<Integer>();

for(Integer number: numbers){
Integer square = new Integer(number.intValue() * number.intValue());

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.intValue() > max){
max = number.intValue();
}
}
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.intValue() < min){
min = number.intValue();
}
}
return min;
}

private static int getSum(List numbers){
int sum = (int)(numbers.get(0));

for(int i=1;i < numbers.size();i++){
sum += (int)numbers.get(i);
}
return sum;
}

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

Execute the above script and the output is as follows:

$ javac Java8Tester.java 
$ java Java8Tester
Using Java 7: 
List: [abc, bc, efg, abcd, jkl]
Number of empty characters: 2
The number of strings with a length of 3 is: 3
The filtered list: [abc, bc, efg, abcd, jkl]
Merge strings: abc, bc, efg, abcd, jkl
Square List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
The largest number in the list: 19
The smallest number in the list: 1
Sum of all numbers: 85
Average: 9
Random number: 
-393170844
-963842252
447036679
-1043163142
-881079698
221586850
-1101570113
576190039
-1045184578
1647841045
Using Java 8: 
List: [abc, bc, efg, abcd, jkl]
Number of empty strings: 2
The number of strings with a length of 3 is: 3
The filtered list: [abc, bc, efg, abcd, jkl]
Merge strings: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
The largest number in the list: 19
The smallest number in the list: 1
Sum of all numbers: 85
Average: 9.4444444444445
Random number: 
-1743813696
-1301974944
-1299484995
-779981186
136544902
555792023
1243315896
1264920849
1472077135
1706423674
Number of empty strings: 2

Topics: Java SQL Database