Saturday, August 14, 2021

Java 8: Stream operations with examples

This article will give practical implementation of each of the stream intermediate and terminal operations. Please refer Java8 Stream Introduction to get basic understanding of streams. 

Please refer below code and comments for details of all the stream operations.


       


package java8;
import java.util.*;

public class EmployeeDB {
	public static List<Employee> getEmployeeList(){
		List<Employee> empList = Arrays.asList(
				//int eId, String fName, String lName, double salary, List<Integer> phNumbers
				new Employee(5, "Sonu", "Panjabi", 1000, Arrays.asList(1234, 2345)),
				new Employee(7, "Ganu", "Marathi", 1500, Arrays.asList(3456, 4567)),
				new Employee(8, "Manu", "Bangali", 2000, Arrays.asList(5678, 6789)),
				new Employee(4, "Tonu", "Bihari", 3000, Arrays.asList(7890, 8901)),
				new Employee(1, "Kanu", "Asami", 3500, Arrays.asList(9012, 1230)),
				new Employee(6, "Ranu", "Kashmiri", 4000, Arrays.asList(9876, 8765)),
				new Employee(2, "Janu", "Kannadi", 4500, Arrays.asList(7654, 6543)),
				new Employee(3, "Monu", "Gujrathi", 5000, Arrays.asList(5432, 4321))
				);
		return empList;
	}
}
package java8.streammethods;

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

import java8.Employee;
import java8.EmployeeDB;

public class StreamMethods {
	public static void main(String[] args) {
		//boolean	allMatch(Predicate<? super T> predicate) 
		//Returns whether all elements of this stream match the provided predicate. 
		System.out.println("ALL employee contains letter u in first name: "+
				EmployeeDB.getEmployeeList().stream().allMatch(a -> a.getfName().contains("u")));
		
		//boolean	anyMatch(Predicate<? super T> predicate)
		//Returns whether any elements of this stream match the provided predicate. 
		System.out.println("Is there ANY employee with salary = 2500: "+
				EmployeeDB.getEmployeeList().stream().anyMatch(a-> a.getSalary() == 2500));
		
		//static <T> Stream.Builder<T>	builder()
		//Returns a builder for a Stream. 
		Stream.Builder<Object> bld = Stream.builder().add("a").add("b").add("c");
		System.out.println("Total elements in build stream are :"+bld.build().count());
		
		//<R,A> R	collect(Collector<? super T,A,R> collector)
		//Performs a mutable reduction operation on the elements of this stream using a Collector. 
		//AND
		//Stream<T>	filter(Predicate<? super T> predicate)
		//Returns a stream consisting of the elements of this stream that match the given predicate. 
		List<Employee> emps = EmployeeDB.getEmployeeList().stream().filter(a -> a.getlName().startsWith("B")).collect(Collectors.toList());
		System.out.println("Employees last name starting with B are :"+emps.stream().map(a->a.getlName()).collect(Collectors.toList()));
		
		//<R> R	collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
		//Performs a mutable reduction operation on the elements of this stream. 
		List<Double> salList = EmployeeDB.getEmployeeList().stream().map(a -> a.getSalary()).collect(Collectors.toList());
		Supplier<Employee> supl1 = Employee::new;
		BiConsumer<Employee, Double> bic3 = (a, b) -> a.setSalary(a.getSalary()+b);
		BiConsumer<Employee, Employee> bic4 = (a, b) -> a.setSalary(a.getSalary()+b.getSalary());
		System.out.println("Sum of all employee salary is :"+salList.stream().collect(supl1, bic3, bic4).getSalary());
		
		//static <T> Stream<T>	concat(Stream<? extends T> a, Stream<? extends T> b)
		//Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream. 
		Stream<Employee> emp1 = EmployeeDB.getEmployeeList().stream().filter(a->a.getlName().startsWith("B"));
		Stream<Employee> emp2 = EmployeeDB.getEmployeeList().stream().filter(a->a.getlName().startsWith("K"));
		System.out.println("Total records in stream are :"+Stream.concat(emp1, emp2).count());
		
		//long	count()
		//Returns the count of elements in this stream. 
		System.out.println("Total records are: "+EmployeeDB.getEmployeeList().stream().count());
		
		//Stream<T>	distinct()
		//Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream. 
		System.out.println("Total distinct records are: "+EmployeeDB.getEmployeeList().stream().distinct().count());
		
		//static <T> Stream<T>	empty()
		//Returns an empty sequential Stream. 
		Stream<Employee> str = Stream.empty();
		
		//Optional<T>	findAny() 
		//Returns an Optional describing some element of the stream, or an empty Optional if the stream is empty. 
		Optional<Employee> emp = str.findAny();//OR
		Optional<Employee> emp3 =EmployeeDB.getEmployeeList().stream().findAny();
		System.out.println("Empty Stream output: "+emp.isPresent()+" and non-Empty output: "+emp3.isPresent());
		
		//Optional<T>	findFirst()
		//Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. 
		Stream<Employee> str1 = Stream.empty();
		Optional<Employee> emp4 = str1.findFirst();//OR
		Optional<Employee> emp5 = EmployeeDB.getEmployeeList().stream().findFirst();
		System.out.println("Empty Stream output: "+emp4.isPresent()+" and non-Empty output: "+emp5.isPresent());
		
		//<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
		//Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 
		List<List<Integer>> phNumbers =  EmployeeDB.getEmployeeList().stream().map(a -> a.getPhNumbers()).collect(Collectors.toList());
		System.out.println("Map: "+ phNumbers.stream().map(a -> a).collect(Collectors.toList()));
		System.out.println("flatMap: "+ phNumbers.stream().flatMap(a -> a.stream()).collect(Collectors.toList()));
		
		//DoubleStream	flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
		//Returns an DoubleStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 
		List<String> lNames = EmployeeDB.getEmployeeList().stream().map(a -> a.getlName()).collect(Collectors.toList());
		lNames.stream().flatMapToDouble(a -> DoubleStream.of(a.length())).forEach(System.out::println);
		
		//IntStream	flatMapToInt(Function<? super T,? extends IntStream> mapper)
		//Returns an IntStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 
		lNames.stream().flatMapToInt(a -> IntStream.of(a.length())).forEach(System.out::println);
		
		//LongStream	flatMapToLong(Function<? super T,? extends LongStream> mapper)
		//Returns an LongStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. 
		lNames.stream().flatMapToLong(a -> LongStream.of(a.length())).forEach(System.out::println);
		
		//void	forEach(Consumer<? super T> action)
		//Performs an action for each element of this stream. 
		EmployeeDB.getEmployeeList().stream().map(a -> a.getlName()).forEach(System.out::println);
		
		//void	forEachOrdered(Consumer<? super T> action)
		//Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order. 
		EmployeeDB.getEmployeeList().stream().map(a -> a.getlName()).forEachOrdered(System.out::println);
		
		//static <T> Stream<T>	generate(Supplier<T> s)
		//Returns an infinite sequential unordered stream where each element is generated by the provided Supplier. 
		//It returns an infinite stream, hence limiting it to 1, to avoid OutOfMemory error
		System.out.println(Stream.generate(EmployeeDB::getEmployeeList).limit(1).collect(Collectors.toList()));
		
		//static <T> Stream<T>	iterate(T seed, UnaryOperator<T> f)
		//Returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc. 
		System.out.println(Stream.iterate(1, a -> a*2).limit(10).collect(Collectors.toList()));
		
		//Stream<T>	limit(long maxSize)
		//Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length. 
		System.out.println(Stream.iterate(1, a -> a*2).limit(5).collect(Collectors.toList()));
		
		//<R> Stream<R>	map(Function<? super T,? extends R> mapper)
		//Returns a stream consisting of the results of applying the given function to the elements of this stream. 
		System.out.println(EmployeeDB.getEmployeeList().stream().map(a -> a.getlName().toUpperCase()).collect(Collectors.toList()));
		
		//DoubleStream	mapToDouble(ToDoubleFunction<? super T> mapper)
		//Returns a DoubleStream consisting of the results of applying the given function to the elements of this stream. 
		System.out.println("Sum of salary: "+EmployeeDB.getEmployeeList().stream().mapToDouble(a -> a.getSalary()).sum());
		
		//IntStream mapToInt(ToIntFunction<? super T> mapper)
		//Returns an IntStream consisting of the results of applying the given function to the elements of this stream.
		System.out.println("Sum of eIDs: "+EmployeeDB.getEmployeeList().stream().mapToInt(a -> a.geteId()).sum());
		
		//LongStream mapToLong(ToLongFunction<? super T> mapper)
		//Returns a LongStream consisting of the results of applying the given function to the elements of this stream. 
		System.out.println("Long Sum of eIDs: "+EmployeeDB.getEmployeeList().stream().mapToLong(a -> a.geteId()).sum());
		
		//Optional<T> max(Comparator<? super T> comparator)
		//Returns the maximum element of this stream according to the provided Comparator. 
		System.out.println("Max emp is : "+EmployeeDB.getEmployeeList().stream().max((e1, e2) -> e1.getfName().compareTo(e2.getfName())));
		
		//Optional<T> min(Comparator<? super T> comparator)
		//Returns the minimum element of this stream according to the provided Comparator. 
		System.out.println("Min emp is : "+EmployeeDB.getEmployeeList().stream().min((e1, e2) -> e1.getfName().compareTo(e2.getfName())));
		
		//boolean	noneMatch(Predicate<? super T> predicate)
		//Returns whether no elements of this stream match the provided predicate. 
		System.out.println("NoneMatch : "+EmployeeDB.getEmployeeList().stream().noneMatch(a -> a.getfName().equalsIgnoreCase("Ganu")));
		
		//static <T> Stream<T>	of(T... values)
		//Returns a sequential ordered stream whose elements are the specified values. 
		System.out.println("Total values elements: "+Stream.of(1, 2, 3, 4).count());
		
		//static <T> Stream<T>	of(T t)
		//Returns a sequential Stream containing a single element. 
		System.out.println("Total elements: "+Stream.of(EmployeeDB.getEmployeeList()).count());
		
		//Stream<T>	peek(Consumer<? super T> action)
		//Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream. 
		//It is mainly used for debugging purpose i.e. to see the elements as they flow (e.g. check below sysout with Filtered value)
		//If there is no terminal operation peek will NOT result in anything
		System.out.println("Peek: "+ EmployeeDB.getEmployeeList().stream().filter(e -> e.getlName().startsWith("B")).peek(e -> System.out.println("Filtered value"+e)).map(e -> e.getlName().toUpperCase()).collect(Collectors.toList()));
		
		//Optional<T>	reduce(BinaryOperator<T> accumulator)
		//Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any. 
		System.out.println("Reduce longest Lastname: "+ EmployeeDB.getEmployeeList().stream().reduce((e1, e2) -> e1.getlName().length() > e2.getlName().length()?e1:e2).get().getlName());
		
		//T	reduce(T identity, BinaryOperator<T> accumulator)
		//Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. 
		List<Integer> list = Arrays.asList(1, 3, 5, 6, 7, 9);
		System.out.println("Reduce Accumulator :"+list.stream().reduce(2, (i1, i2) -> i1+i2).intValue());
		
		//<U> U	reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
		//Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions. 
		System.out.println("Reduce BiFunction :"+list.stream().reduce(2, (a, b)-> a+b, (a, c) -> a+c).intValue());
		
		//Stream<T>	skip(long n)
		//Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream. 
		System.out.println("Skip: "+ EmployeeDB.getEmployeeList().stream().skip(3).map(a->a.getfName()).collect(Collectors.toList()));
		
		//Stream<T>	sorted()
		//Returns a stream consisting of the elements of this stream, sorted according to natural order. 
		System.out.println("Sorted: "+ EmployeeDB.getEmployeeList().stream().map(a->a.getfName()).sorted().collect(Collectors.toList()));
		
		//Stream<T>	sorted(Comparator<? super T> comparator)
		//Returns a stream consisting of the elements of this stream, sorted according to the provided Comparator. 
		System.out.println("Sorted Comparator: "+ EmployeeDB.getEmployeeList().stream().sorted((e1, e2)-> e1.getlName().compareTo(e2.getlName())).map(a->a.getlName()).collect(Collectors.toList()));
		
		//Object[]	toArray()
		//Returns an array containing the elements of this stream. 
		System.out.println("toArray: "+ Arrays.toString(EmployeeDB.getEmployeeList().stream().map(a->a.getfName()).toArray()));
		
		//<A> A[]	toArray(IntFunction<A[]> generator)
		//Returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing. 
		List<Integer> nums = Arrays.asList(2, 3, 5, 7, 11);
		System.out.println(Arrays.toString(nums.stream().toArray(a -> new Integer[a])));
	}
}
Please add more practical examples in comment, which will help others. Thanks.

No comments:

SpringBoot: Features: SpringApplication

Below are a few SpringBoot features corresponding to SpringApplication StartUp Logging ·          To add additional logging during startup...