Streams

 

The key aspect of Stream API is it’s the ability to perform very sophisticated operations such as search, filter, map, or otherwise manipulate data. Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result.

As a general rule, a stream operation by itself does not modify the data source. For example, sorting a stream does not change the order of the source. Rather, sorting stream results in creating a new stream that produces the sorted result.

Features:

  • A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
  • Streams don’t change the original data structure, they only provide the result as per the pipelined methods.
  • Each intermediate operation is lazily executed and returns a stream as a result, hence various intermediate operations can be pipelined. Terminal operations mark the end of the stream and return the result.

Intermediate Operations On Streams (Intermediate operation is lazily executed and returns a stream as a result, hence various intermediate operations can be pipelined.)

streams-f1

  • map: The map method is used to map the items in the collection to other objects according to the Function passed as an argument. map() creates a new stream after applying a function to all elements of the original stream.
List number = Arrays.asList(2,3,4,5);
List square = number.stream().map(x->x*x).collect(Collectors.toList());

String number = Stream.of(9, 4, 6, 1, 3, 5).map(num -> num + "").collect(Collectors.joining(","));
// 9,4,6,1,3,5

double average = Stream.of("1","5","10","4").mapToInt(Integer::parseInt).average().getAsDouble();
// 5
  • filter: The filter method is used to select elements as per the Predicate passed as argument.
List names = Arrays.asList("Reflection","Collection","Stream");
List result = names.stream().filter(s->s.startsWith("S")).collect(Collectors.toList());
  • sorted: The sorted method is used to sort the stream.
List names = Arrays.asList("Reflection","Collection","Stream");
List result = names.stream().sorted().collect(Collectors.toList());

List<Integer> numbers = Stream.of(9,4,6,1,3,5).sorted((a, b) -> {

	return a.compareTo(b);

}).collect(Collectors.toList());

System.out.println("numbers: " + numbers.toString());
numbers: [1, 3, 4, 5, 6, 9]

Terminal Operations On Streams(Terminal operations mark the end of the stream and return the result)

  • collect: The collect method is used to return the result of the intermediate operations performed on the stream. It is a way to get elements out of the stream.
List number = Arrays.asList(2,3,4,5,3);
Set square = number.stream().map(x->x*x).collect(Collectors.toSet());

Set<Integer> set = Stream.of(1, 2, 3).collect(Collectors.toCollection(HashSet::new));

//[1, 2, 3]
		
Map<Integer,String> map = Stream.of(1, 2, 3).collect(Collectors.toConcurrentMap(num -> num, num -> num+""));
	
//{1=1, 2=2, 3=3}
  • forEach: The forEach method is used to iterate through every element of the stream.
List number = Arrays.asList(2,3,4,5);
number.stream().map(x->x*x).forEach(y->System.out.println(y));
  • reduce: The reduce method is used to reduce the elements of a stream to a single value.
    The reduce method takes a BinaryOperator as a parameter.
List number = Arrays.asList(2,3,4,5);
int even = number.stream().filter(x->x%2==0).reduce(0,(ans,i)-> ans+i);
int initialValue = 5;
		
int reducedNumber = Stream.of(1, 2, 3).reduce(initialValue, (num, index)-> {
			System.out.println("num: "+num+", index: "+index);
			return index;
		});
		
System.out.println("reducedNumber: "+reducedNumber);
num: 3, index: 1
num: 1, index: 2
num: 2, index: 3
reducedNumber: 3

 

String listToString = Stream.of("Folau", "Kinga", "Laulau").collect(Collectors.joining(", ", "(", ")"));

System.out.println("listToString: " + listToString);
listToString: (Folau, Kinga, Laulau)

 

 

 

 

 

 

 

 

 

Examples

foreach – terminal operation

Performs an action for each element of this stream.

List<String> words = Arrays.asList("I", "can", "program", "in", "Java");
words.stream().forEach(System.out::println);

allMatch() – terminal operation

Returns whether all elements of this stream match the provided predicate. May not evaluate the predicate on all elements if not necessary for determining the result. If the stream is empty then true is returned and the predicate is not evaluated.

// Creating a list of Integers 
List<Integer> list = Arrays.asList(3, 4, 6, 12, 20); 
      
// Check if all elements of stream 
// are divisible by 3 or not using  
// Stream allMatch(Predicate predicate) 
boolean answer = list.stream().allMatch(n-> n % 3 ==0); 

map() – intermediate operation

Returns a stream consisting of the results of applying the given function to the elements of this stream.

// Creating a list of Integers 
List<Integer> list = Arrays.asList(3, 6, 9, 12, 15); 
  
// Using Stream map(Function mapper) and 
// displaying the corresponding new stream 
list.stream().map(number -> number * 3).forEach(System.out::println)

collect() – terminal operation

Stream.collect() method used to receive elements from a stream and store them in a collection.

users.add(new User("John", "john@gmail.com",100000));
users.add(new User("Peter", "peter@gmail.com", 50000));
 
// find employees whose salaries are above 100000
List<User> filteredList = users.stream().filter(user->user.getSalary() > 100000).collect(Collectors.toList());

// Collections to Map
Map<Integer, String> result1 = users.stream().collect(
                Collectors.toMap(User::getId, User::getName));
Map<Integer, String> result2 = users.stream().collect(
                Collectors.toMap(u -> u.getId(), u -> u.getName()));
Map result3 = list.stream().collect(
                        Collectors.toMap(
                                u -> u.getName(), u -> u.getId(), 
                                (oldValue, newValue) -> oldValue,  
                                LinkedHashMap::new
                        ));
int sum = Stream.of(1, 2, 3).collect(Collectors.summingInt(Integer::intValue));

System.out.println("sum: " + sum);
sum: 6

 

long count() – terminal operation

Returns the count of elements in this stream.

long count = Arrays.asList("I","can","program","in","java").stream().count();
System.out.printf("There are %d elements in the stream %n", count);

iterate() – intermediate operation

Create values on demand

//Stream.iterate(initial value, next value)
Stream.iterate(0, n -> n + 1)
                .limit(10)
                .forEach(x -> System.out.println(x));

int numOfIterations = 5;
		int initialValue = 3;

		Stream.iterate(initialValue, n -> {
			return n * 2;
		}).limit(numOfIterations).forEach(x -> System.out.println(x));

Stream Creation

Stream.of("Folau", "Kinga", "Laulau").forEach((name) -> {
			System.out.println("name1: " + name);
		});
		Stream.builder().add("Folau").add("Kinga").add("Laulau").build().forEach((name) -> {
			System.out.println("name2: " + name);
		});

findFirst()

findFirst() returns the first element in the stream.

Stream.of("Folau", "Kinga", "Laulau").filter(name -> name.contains("lau")).forEach((name) -> {
	System.out.println("name: " + name);
});
//name: Folau
//name: Laulau

parallel – run executions in multiple threads.

int numOfIterations = 20;
int initialValue = 3;
		
int sum = Stream.iterate(initialValue, n -> {
			return n * 2;
		}).limit(numOfIterations).parallel().collect(Collectors.summingInt(Integer::intValue));

System.out.println("sum: " + sum);

 

Resources

 




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Leave a Reply

Your email address will not be published. Required fields are marked *