0% found this document useful (0 votes)
3 views30 pages

Java Stream API2

The document provides an overview of the Java Stream API introduced in Java 8, which allows developers to process data in a declarative manner and leverage multicore architectures. It covers various stream operations such as filtering, mapping, reducing, and collecting, along with examples demonstrating their usage. Additionally, it discusses parallel processing, lazy evaluation, and terminal operations within the Stream API.

Uploaded by

eramchegyt
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views30 pages

Java Stream API2

The document provides an overview of the Java Stream API introduced in Java 8, which allows developers to process data in a declarative manner and leverage multicore architectures. It covers various stream operations such as filtering, mapping, reducing, and collecting, along with examples demonstrating their usage. Additionally, it discusses parallel processing, lazy evaluation, and terminal operations within the Stream API.

Uploaded by

eramchegyt
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 30

Java

Stream
API
softserve
Agenda
•Class java.util.Stream
•Stream API. Aggregate Operations
•Case Studies
Class
java.util.Stream
Pipeline
Class Stream
• Stream is a new abstract layer introduced in Java 8.
• Using stream, you can process data in a declarative way.
• Using collections framework in Java, a developer has to use loops and make repeated
checks.
• Another concern is efficiency; as multi-core processors are available at ease; a Java
developer has to write parallel code processing that can be pretty error-prone.
• To resolve such issues, Java 8 introduced the concept of stream that lets the developer to
process data declaratively and leverage multicore architecture without the need to write any
specific code for it.
Class Stream
• Stream represents a sequence of objects from a source, which supports aggregate
operations.
• Characteristics of a Stream
• Sequence of elements. A stream provides a set of elements of specific type in a
sequential manner.
• A stream gets/computes elements on demand. It never stores the elements
• Source. Stream takes Collections, Arrays, or I/O resources as input source.
• Aggregate operations. Stream supports aggregate operations like
• filter,
• map,
• limit,
• reduce,
• find,
• match, and so on.
Class Stream. Source
• Create a source as a list of lines
List<String> strCollection = new ArrayList<>();
strCollection.add("aa1");
strCollection.add("bb1");
strCollection.add("aa2");
strCollection.add("cc1");
strCollection.add("aa3");
strCollection.add("bb2");
strCollection.add("cc2");
• You can quickly create streams using the calls to Collection.stream() or
Collection.parallelStream()
strCollection.stream()
.forEach(System.out::println);
Class Stream. Source
• Characteristic
• Return another stream
• Lazy
• Are familiar to builder pattern
• Should be non-interfering and stateless
• For example
• Collections:
List<T> list;
Stream<T> stream = list.stream();
• Generators:
Stream<Integer> stream = Stream.generate(() -> x++);
• Utilities:
LongStream stream = LongStream.range(0, 100);
Class Stream
• Pipelining. Most of the stream operations return stream itself so that their result can be
pipelined.
• These operations are called intermediate operations and their function is to take input,
process them, and return output to the target.
• collect() method is a terminal operation which is normally present at the end of the
pipelining operation to mark the end of the stream
• Automatic iterations. Stream operations do the iterations internally over the source
elements provided, in contrast to Collections where explicit iteration is required
Stream API.
Aggregate Operations
Filter
• With Java 8, Collection interface has two methods to generate a Stream
• stream() − Returns a sequential stream considering collection as its source
• parallelStream() − Returns a parallel Stream considering collection as its source
• The "filter" method is used to eliminate elements based on a criteria
• The following code segment prints a count of empty strings using filter
List<String> strings = Arrays
.asList("abc", "", "bc", "abcd", "", "jklmn");
List<String> filtered = strings
.stream()
.filter(str -> !str.isEmpty())
.collect(Collectors.toList());
System.out.println(strings);
System.out.println(filtered);
Filter
• The Filter operation accepts a predicate that filters all elements of the stream
List<String> strCollection = new ArrayList<>();
strCollection.add("aa1");
strCollection.add("bb1");
strCollection.add("aa2");
strCollection.add("cc1");
//
strCollection
.stream()
.filter((s) -> s.startsWith("a"))
.forEach(System.out::println);
// "aa1", "aa2"
ForEach. Limit
• limit
• The ‘limit’ method is used to reduce the size of the stream

• forEach
• Stream has provided a new method ‘forEach’ to iterate each element of the stream
• The following code segment shows how to print 10 random numbers using forEach

Random random = new Random();


random.ints()
.limit(10)
.forEach(System.out::println);
Sorted
• sorted
• The "sorted" method is used to sort the stream
• Sorted operation is an intermediate operation
• Оperation returns a sorted representation of the stream.
• By default Items are sorted in the usual way.
List<String> arrList = Arrays.asList("D", "A", "C", "B", "E");
arrList.stream()
.forEach(System.out::print); // DACBE
arrList.stream()
.sorted()
.forEach(System.out::print); // ABCDE
Sorted
• sorted
• You can provide your own comparator
Stream<String> arrStream = Stream.of("D", "A", "C", "B", "E");
List<String> arrlist = arrStream
.collect(Collectors.toList());
arrlist
.stream()
.sorted((s1,s2)->s2.compareTo(s1))
.forEach(System.out::print); // EDCBA
arrlist.stream()
.forEach(System.out::print); // DACBE
Map. Distinct
• map
• The ‘map’ method is used to map each element to its corresponding result.
• The following code segment prints unique squares of numbers using map
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// get list of unique squares
List<Integer> sqrList = numbers
.stream()
.map(i -> i * i)
.distinct()
.collect(Collectors.toList());
System.out.println(sqrList); // [9, 4, 49, 25]
sqrList.stream()
.forEach(System.out::print); // 9 4 49 25
Map
• The following example converts each string to a uppercase string.
List<String> strCollection = Arrays
.asList("aa1", "bb1", "aa2", "cc1", "aa3");

strCollection
.stream()
.forEach(System.out::println); // aa1 bb1 aa2 cc1 aa3

strCollection
.stream()
.map(String::toUpperCase)
.sorted((a, b) -> b.compareTo(a))
.forEach(System.out::println); // CC1 BB1 AA3 AA2 AA1
AnyMatch
• Match
• To check whether a stream satisfies a given predicate, various matching operations are used
• All matching operations are terminal and return a result of type Boolean

List<String> strCollection = Arrays


.asList("aa1", "bb1", "aa2", "cc1", "aa3");

boolean anyStartsWithA =
strCollection
.stream()
.anyMatch((s) -> s.startsWith("a"));
System.out.println(anyStartsWithA); // true
AllMatch. NoneMatch
boolean allStartsWithA =
strCollection
.stream()
.allMatch((s) -> s.startsWith("a"));
System.out.println(allStartsWithA); // false

boolean noneStartsWithZ =
strCollection
.stream()
.noneMatch((s) -> s.startsWith("z"));
System.out.println(noneStartsWithZ); // true
Count
• count
• The Count operation is the final operation and returns the number of elements in the
stream.
• The return type is long.
List<String> strCollection = Arrays
.asList("aa1", "bb1", "aa2", "cc1", "aa3");

long startsWithA =
strCollection
.stream()
.filter((s) -> s.startsWith("a"))
.count();
System.out.println(startsWithA); // 3
Count
• count
• The following code segment prints a count of empty strings using filter

List<String> strings =
Arrays.asList("abc", "", "eg", "abcd", "", "jklmn");

// get count of empty string


long count = strings.stream()
.filter(string -> string.isEmpty())
.count();
System.out.println(count); // 2
Reduce
• reduce
• This terminal operation combines all elements of the stream into a single result according to
a given function
• The result is an optional value
List<String> strCollection = Arrays
.asList("aa1", "bb1", "aa2", "cc1", "aa3");
Optional<String> reduced =
strCollection
.stream()
.sorted()
.reduce((s1, s2) -> s1 + "*" + s2);
reduced
.ifPresent(System.out::println); // aa1*aa2*aa3*bb1*cc1
Reduce
• reduce
• Sum and maximum of all elements
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
Integer resSum = numbers
.stream()
.reduce(0, (sum, p) -> sum = sum + p);
System.out.println(resSum); // 25

Integer resMax = numbers


.stream()
.reduce(numbers.get(0), (max, p) -> max < p ? p : max);
System.out.println(resMax); // 7
Collectors
• collectors
• Collectors are used to combine the result of processing on the elements of a stream
• Collectors can be used to return a list or a string
List<String> strings = Arrays
.asList("abc", "", "bc", "eg", "abd", "", "jklmn");
List<String> filtered = strings.stream()
.filter(string -> !string.isEmpty())
.collect(Collectors.toList());
System.out.println(filtered); // [abc, bc, eg, abd, jklmn]
String mergedString = strings.stream()
.filter(string -> !string.isEmpty())
.collect(Collectors.joining(", "));
System.out.println(mergedString); // abc, bc, eg, abd, jklmn
Statistics
• statistics
• Statistics collectors are introduced to calculate all statistics when stream processing is being
done
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers
.stream()
.mapToInt((x) -> x)
.summaryStatistics();
System.out.println("Highest " + stats.getMax()); // 7
System.out.println("Lowest " + stats.getMin()); // 2
System.out.println("Sum " + stats.getSum()); // 25
System.out.println("Average " + stats.getAverage());
// 3.5714285714285716
Parallel Processing
• Parallel Processing
• parallelStream() is the alternative of stream for parallel processing
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

int max = 1000000;


List<String> arr = new ArrayList<>(max);
for (int i = 0; i < max; i++) {
UUID uuid = UUID.randomUUID();
arr.add(uuid.toString());
}
Parallel Processing. Sorting
long time0 = System.nanoTime();
long count = arr
//.parallelStream() // sequential sort 618 ms
.stream() // parallel sort 333 ms
.sorted()
.count();

System.out.println(count);
long time1 = System.nanoTime();
long millis = TimeUnit.NANOSECONDS.toMillis(time1 - time0);
System.out.println(String.format("sort %d ms", millis));
Lazy Evaluation
• Streams are lazy because intermediate operations are not evaluated until terminal operation
is invoked
• Each intermediate operation creates a new stream, stores the provided operation/function
and return the new stream
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
System.out.println("Original numbers: " + numbers);
// [3, 2, 2, 3, 7, 3, 5]
Stream<Integer> nums = numbers
.stream()
.filter(n -> n > 2);
numbers.set(1, 10);
System.out.println("Updated numbers: " + numbers);
// [3, 10, 2, 3, 7, 3, 5]
System.out.println("nums count: " + nums.count()); // 6
Terminal Operations
• reducers: reduce, findFirst, findAny
• collectors: put into collection
• forEach: perform operation over elements
• iterator: get elements one by one

• findFirst/findAny: return appropriate element


• collect: present result in any other data structure
• count: return number of elements in the stream
• anyMatch/noneMatch/allMatch: return true due to condition
• min/max: return min / max element
• forEach /forEachOrdered: applies function for each element
• toArray: return array of values of the stream
Maps
• Associative arrays (map) do not support streams.
• Associative arrays support various useful methods that solve common tasks

Map<Integer, String> map = new HashMap<>();


for (int i = 0; i < 5; i++) {
map.putIfAbsent(i, "num" + i);
}
map.forEach((key, value) -> System.out.print(value + " "));
// num0 num1 num2 num3 num4

map.computeIfPresent(3, (key, value) -> key + "_" + value);


System.out.print(map.get(3));
// 3_num3
THANKS

You might also like