Introduced in Java 8, the Stream is an API for processing Collection and its elements.
A stream is a chain of operations which are pipelined to produce the result.
The features of Java stream are –
Structure: [CollectionType].stream()
.intermediateOperation1()
.intermediateOperation2()
.
.
.terminateOperation() //end of chain
Different Operations On Streams-
map: The map method is used to returns a stream consisting of the results of applying the given function to the elements of this stream.
List number = Arrays.asList(2,3,4,5);
List square = number.stream().map(x->x*x).collect(Collectors.toList());
filter: The filter method is used to pick up elements which match the boolean-valued function (also known as Predicate).
List<String> names = Arrays.asList("Vietnam", "Ireland", "United States", "Venezuela");
List<String> namesWith7Characters = names.stream().filter(o->{
if(o.length() == 7) return true;
else return false;
}).collect(Collectors.toList());
sorted: The sorted method is used to sort the stream.
List<String> names = Arrays.asList("Vietnam", "Ireland", "United States", "Singapore");
List<String> sortedNames = names.stream().sorted((o1,o2)->{
if (o1.charAt(0) > o2.charAt(0)) return 1;
else return -1;
}).collect(Collectors.toList());
collect: The collect method is used to return the result of the intermediate operations performed on the stream.
List<Integer> number = Arrays.asList(2,3,4,5,3);
Set<Integer> square = number.stream().map(x->x*x).collect(Collectors.toSet());
forEach: The forEach method is used to iterate through every element of the stream.
List<Integer> number = Arrays.asList(2,3,4,5);
number.stream().map(x->x*x).forEach(y->System.out.println(y));
reduce: to produce one single result from a sequence of elements, by applying repeatedly a combining operation to the elements in the sequence.
Before we look deeper into using the Stream.reduce() operation, let's break down the operation's participant elements into separate blocks. That way, we'll understand more easily the role that each one plays:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
int result = numbers.stream()
.reduce(0, (subtotal, element) -> {
return subtotal + element;
});
assertThat(result).isEqualTo(21);
We can also use Stream.reduce() with custom objects that contain non-primitive fields. To do so, we need to provide
Scenario: We want to calculate the average rating points based on many review points. A Rating
object contains a reviewList
. Each Review
object has a point field. We use stream to calculate the sum of review and divide it by the number of review to get the average rating points.
import java.util.*;
public class StreamExample {
public static void main(String[] args) {
Rating rating = new Rating();
rating.add(new Review(6));
rating.add(new Review(8));
rating.add(new Review(10));
System.out.println(rating.avgPoint);
}
}
class Rating{
List<Review> reviewList = new ArrayList<>();
double avgPoint;
void add(Review review){
reviewList.add(review);
computeAvgPoint();
}
void computeAvgPoint(){
int sum = reviewList.stream().map(review -> { // Map a Review Object to Integer
return review.points;
}).reduce(0,(i1,i2)->{ // Reduce terminal to produce a single result
return i1+i2;
});
avgPoint = sum/reviewList.size();
}
}
class Review{
int points;
public Review(int points) {
this.points = points;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
}