YouTip LogoYouTip

Java8 Streams

[![Image 1: Java 8 New Features](#) Java 8 New Features](#) * * * Java 8 API adds a new abstraction called Stream, which allows you to process data in a declarative manner. Stream provides a higher-order abstraction for operations and expressions on Java collections, using an intuitive approach similar to querying data from a database with SQL statements. The Stream API can greatly improve the productivity of Java programmers, allowing them to write efficient, clean, and concise code. This style treats the collection of elements to be processed as a stream, which flows through a pipeline and can be processed at nodes within the pipeline, such as filtering, sorting, aggregation, etc. The element stream undergoes processing through intermediate operations, and finally, a terminal operation yields the result of the previous processing. +--------------------+ +------+ +------+ +---+ +-------+| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|+--------------------+ +------+ +------+ +---+ +-------+ The above flow translates to the following Java code: List 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 queue of elements from a data source that supports aggregate operations. * Elements are objects of a specific type, forming a queue. A Stream in Java does not store elements but computes them on demand. * **Data Source**: The source of the stream. It can be a collection, an array, an I/O channel, a generator, etc. * **Aggregate Operations**: Operations similar to SQL statements, such as filter, map, reduce, find, match, sorted, etc. Unlike previous Collection operations, Stream operations have two fundamental characteristics: * **Pipelining**: Intermediate operations return the stream object itself. This allows multiple operations to be chained into a pipeline, similar to a fluent style. This enables optimizations such as laziness and short-circuiting. * **Internal Iteration**: Previously, iterating over collections was done explicitly outside the collection using Iterator or For-Each, known as external iteration. Stream provides internal iteration, implemented via the Visitor pattern. * * * ## Generating Streams In Java 8, the Collection interface has two methods to generate streams: * **stream()** βˆ’ Creates a serial stream for the collection. * **parallelStream()** βˆ’ Creates a parallel stream for the collection. Liststrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); Listfiltered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); * * * ## forEach Stream provides a new method 'forEach' to iterate over each element in the stream. The following code snippet uses forEach to print 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: Listnumbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); ListsquaresList = numbers.stream().map(i ->i*i).distinct().collect(Collectors.toList()); * * * ## filter The filter method is used to filter elements based on a set condition. The following code snippet uses the filter method to filter out empty strings: Liststrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); long count = strings.stream().filter(string ->string.isEmpty()).count(); * * * ## limit The limit method is used to get a specified number of elements from the stream. The following code snippet uses the limit method to print 10 records: 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 the 10 random numbers output: Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println); * * * ## Parallel Programs parallelStream is an alternative method for parallel processing of streams. In the following example, we use parallelStream to output the count of empty strings: Liststrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); long count = strings.parallelStream().filter(string ->string.isEmpty()).count(); We can easily switch between sequential and parallel execution. * * * ## Collectors The Collectors class implements many reduction operations, such as converting streams into collections and aggregating elements. Collectors can be used to return a list or a string: Liststrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); Listfiltered = 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, some collectors that produce statistical results are also very useful. They are primarily used for primitive types like int, double, long, etc., and can be used to generate statistical results similar to the following. Listnumbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); IntSummaryStatistics stats = numbers.stream().mapToInt((x) ->x).summaryStatistics(); System.out.println("Max: " + stats.getMax()); System.out.println("Min: " + stats.getMin()); System.out.println("Sum: " + stats.getSum()); System.out.println("Average: " + stats.getAverage()); * * * ## Stream Complete Example Place the following code into a file named Java8Tester.java: ## 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: "); Liststrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); System.out.println("List: " +strings); long count = getCountEmptyStringUsingJava7(strings); System.out.println("Empty String Count: " + count); count = getCountLength3UsingJava7(strings); System.out.println("String Count with length 3: " + count); Listfiltered = deleteEmptyStringsUsingJava7(strings); System.out.println("Filtered List: " + filtered); String mergedString = getMergedStringUsingJava7(strings,", "); System.out.println("Merged String: " + mergedString); Listnumbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); ListsquaresList = getSquares(numbers); System.out.println("Squares List: " + squaresList); Listintegers = Arrays.asList(1,2,13,4,15,6,17,8,19); System.out.println("List: " +integers); System.out.println("Max: " + getMax(integers)); System.out.println("Min: " + getMin(integers)); System.out.println("Sum: " + getSum(integers)); System.out.println("Average: " + getAverage(integers)); System.out.println("Random Numbers: "); Random random = new Random(); for(int i=0; istring.isEmpty()).count(); System.out.println("Empty String Count: " + count); count = strings.stream().filter(string ->string.length() == 3).count(); System.out.println("String Count 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("Squares List: " + squaresList); System.out.println("List: " +integers); IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics(); System.out.println("Max: " + stats.getMax()); System.out.println("Min: " + stats.getMin()); System.out.println("Sum: " + stats.getSum()); System.out.println("Average: " + stats.getAverage()); System.out.println("Random Numbers: "); random.ints().limit(10).sorted().forEach(System.out::println); count = strings.parallelStream().filter(string ->string.isEmpty()).count(); System.out.println("Empty String Count: " + count); }private static int getCountEmptyStringUsingJava7(Liststrings){int count = 0; for(String string: strings){if(string.isEmpty()){count++; }}return count; }private static int getCountLength3UsingJava7(Liststrings){int count = 0; for(String string: strings){if(string.length() == 3){count++; }}return count; }private static ListdeleteEmptyStringsUsingJava7(Liststrings){ListfilteredList = new ArrayList(); for(String string: strings){if(!string.isEmpty()){filteredList.add(string); }}return filteredList; }private static String getMergedStringUsingJava7(Liststrings, 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 ListgetSquares(Listnumbers){ListsquaresList = new ArrayList(); 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(Listnumbers){int max = numbers.get(0); for(int i=1;imax){max = number.intValue(); }}return max; }private static int getMin(Listnumbers){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(Listnumbers){return getSum(numbers) / numbers.size(); }} Execute the above script, and the output will be: $ javac Java8Tester.java $ java Java8TesterUsing Java 7: List: [abc, , bc, efg, abcd, , jkl]Empty String Count: 2String Count with length 3: 3Filtered List: [abc, bc, efg, abcd, jkl]Merged String: abc, bc, efg, abcd, jkl Squares List: [9, 4, 49, 25]List: [1, 2, 13, 4, 15, 6, 17, 8, 19]Max: 19Min: 1Sum: 85Average: 9Random Numbers: -393170844-963842252447036679-1043163142-881079698221586850-1101570113576190039-10451845781647841045Using Java 8: List: [abc, , bc, efg, abcd, , jkl]Empty String Count: 2String Count with length 3: 3Filtered List: [abc, bc, efg, abcd, jkl]Merged String: abc, bc, efg, abcd, jkl Squares List: [9, 4, 49, 25]List: [1, 2, 13, 4, 15, 6, 17, 8, 19]Max: 19Min: 1Sum: 85Average: 9.444444444444445Random Numbers: -1743813696-1301974944-1299484995-7799811861365449025557920231243315896126492084914720771351706423674Empty String Count: 2 * * Java 8 New Features](#)
← Python3 Func MapJava Object Wait Timeout Nanos β†’