Java 8 – Stream reduce() method with examples

In this article, we will discuss Stream’s reduce() method in detail with examples

1. Stream reduce() method :

  • This Stream method is a terminal operation which performs reduction on the given stream and returns a reduced (or single) value
  • There are 3 variants of reduce() method
  • Method signature 1 :- Optional<T> reduce(BinaryOperator<T> accumulator)
  • Method signature 2 :- T reduce(T identity, BinaryOperator<T> accumulator)
  • Method signature 3 :- <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
  • reduce() method helps to derive sum of the Stream, searching max/mix element amongst Stream elements or finding average and performing String concatenation
  • We can utilize this method for Map and reduce functionality



2. Stream reduce() method with accumulator :

  • This is the first variant of the reduce() method which takes only one argument BinaryOperator as accumulartor
  • This accumulator perform reduction on the given Stream elements using Lambda expression or Method Reference
  • Method signature :- Optional<T> reduce(BinaryOperator<T> accumulator)
  • Throws NullPointerException if the result of the reduction is null

2.1 Summing Stream elements

  • In this Stream reduce() example, we are going to summate all elements present in the Stream using Lambda Expression as well as Method Reference
  • For lambda expressionreduce((m,n) -> m+n)
  • For method referencereduce(Integer::sum)
  • Both these approaches returns OptionalInt
  • We can easily check whether value is present using ifPresent() method and print to console, if present
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;
import java.util.OptionalInt;

public class StreamReduceForSumUsingReduceAccumulator {

	public static void main(String[] args) {

		// primitive int[] array
		int[] intArray = {
				17, 23, 29, 31, 37, 41, 43, 47, 53, 58
		};

		// 1.1 reduce() - sum using Lambda Expression
		OptionalInt optionalIntResult1 = Arrays
				.stream(intArray)
				.reduce((m,n) -> m+n); // summation

		// 1.2 get value, if present
		optionalIntResult1.ifPresent(
				sum -> System.out.println("Stream.reduce() - "
						+ "Sum using Lambda Expresion = " 
						+ sum));


		// 2.1 reduce() - sum using Method Reference
		OptionalInt optionalIntResult2 = Arrays
				.stream(intArray)
				.reduce(Integer::sum); // summation

		// 2.2 get value, if present
		optionalIntResult2.ifPresent(
				sum -> System.out.println("Stream.reduce() - "
						+ "Sum using Method Reference = " 
						+ sum));
	}
}

Output:

Stream.reduce() - Sum using Lambda Expresion = 379
Stream.reduce() - Sum using Method Reference = 379

2.2 Searching maximum/minimum element from Stream

  • In this Stream reduce() example, we are going to find greatest and smallest element from Stream using Lambda Expression as well as Method Reference
  • For finding greatest/maximum element from Stream, use reduce((x, y) -> (x > y ? x : y)) for lambda expression and reduce(Integer::max) for method reference
  • For finding smallest/minimum element from Stream, use reduce((x, y) -> (x < y ? x : y)) for lambda expression and reduce(Integer::min) for method reference
  • All the above approaches returns OptionalInt which has a useful called ifPresent() to check whether value is present and we can print to console, if present
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;

public class FindMinAndMaxUsingReduceAccumulator {

	public static void main(String[] args) {

		// primitive int[] array
		int[] intArray = {
				17, 23, 29, 31, 37, 41, 43, 47, 53, 59
		};

		// 1.1 reduce() - find Maximum element using Lambda Expression
		Arrays
		.stream(intArray)
		.reduce((x, y) -> (x > y ? x : y)) // find greatest
		.ifPresent(
				max -> System.out.println("Stream.reduce() - "
						+ "Maximum element using Lambda Expresion = " 
						+ max));

		// 1.2 reduce() - find Maximum element using Method Reference
		Arrays
		.stream(intArray)
		.reduce(Integer::max) // find greatest
		.ifPresent(
				max -> System.out.println("\nStream.reduce() - "
						+ "Maximum element using Method Reference = " 
						+ max));


		// 2.1 reduce() - find Minimum using Lambda Expression
		Arrays
		.stream(intArray)
		.reduce((x, y) -> (x < y ? x : y)) // find smallest
		.ifPresent(
				min -> System.out.println("\n\nStream.reduce() - "
						+ "Minimum element using Lambda Expresion = " 
						+ min));

		// 2.2 reduce() - find Minimum using Method Reference
		Arrays
		.stream(intArray)
		.reduce(Integer::min) // find smallest
		.ifPresent(
				min -> System.out.println("\nStream.reduce() - "
						+ "Minimum element using Method Reference = " 
						+ min));
	}
}

Output:

Stream.reduce() - Maximum element using Lambda Expresion = 59

Stream.reduce() - Maximum element using Method Reference = 59


Stream.reduce() - Minimum element using Lambda Expresion = 17

Stream.reduce() - Minimum element using Method Reference = 17

2.3 Finding average from Stream elements

  • In this Stream reduce() example, we are going to find average from Stream elements
  • To get average, we have to find summation of all elements using either Lambda Expression or Method Reference
  • Then we have to divide this sum by number of elements present in the Stream which will return integer part discarding fractional part
  • The above approach isn’t the optimal way, as it discards fractional portion thereby not providing accurate result
  • Therefore, we can use average() method of IntStream to get average as double value which is the most accurate one
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;

public class FindAverageUsingReduceAccumulator {

	public static void main(String[] args) {

		// int[] array
		int[] intArray = {
				17, 23, 29, 31, 37, 41, 43, 47, 53
		};

		// 1. Stream.reduce() - average using Lambda Expression
		int average1 = Arrays
				.stream(intArray)
				.reduce((m,n) -> m+n)
				.orElse(0) / intArray.length;

		System.out.println("Stream.reduce() - "
				+ "Average using Lambda Expression = " 
				+ average1);


		// 2. Stream.reduce() - average using Method Reference
		int average2 = Arrays
				.stream(intArray)
				.reduce(Integer::sum)
				.orElse(0) / intArray.length;

		System.out.println("\nStream.reduce() - "
				+ "Average using Method Reference = " 
				+ average2);


		// 3. using average() of IntStream
		double average3 = Arrays
				.stream(intArray)
				.average()
				.getAsDouble();

		System.out.println("\nUsing average() of IntStream = " 
				+ average3);
	}
}

Output:

Stream.reduce() - Average using Lambda Expression = 35

Stream.reduce() - Average using Method Reference = 35

Using average() of IntStream = 35.666666666666664

2.4 String Concatenation

  • In this Stream reduce() example, we are going to concatenate all Strings present in the Stream using Lambda Expression as well as Method Reference
  • For lambda expression use reduce((str1, str2) -> str1 + ” ” + str2) – this approach helps us to provide delimiter in between 2 String values while concatenating
  • For method reference use reduce(String::concat) – this approach just helps us to concatenate all String together
  • Both these approaches returns Optional<String>
  • We can easily check whether value is present using ifPresent() method and print to console, if present
  • There are 2 more use-cases, where in 1st use-case we are converting String into upper case and then concatenating with space delimiter and in the 2nd use-case we are concatenating with pipe (|) as delimiter between 2 String values
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;
import java.util.Optional;

public class StringConcatenationUsingReduceAccumulator {

	public static void main(String[] args) {

		// String[] array
		String[] strArray = {
				"India",
				"is",
				"a",
				"Beautiful",
				"country"
		};

		// 1.1 Stream.reduce() - string concatenation using lambda
		Optional<String> resultLEx = Arrays
				.stream(strArray)
				.reduce((str1, str2) -> str1 + " " + str2);

		// print result, if present
		resultLEx.ifPresent(System.out::println);


		// 1.2 Stream.reduce() - string concatenation using method ref
		Optional<String> resultMRef = Arrays
				.stream(strArray)
				.reduce(String::concat);

		// print result, if present
		resultMRef.ifPresent(System.out::println);


		// 1.3 upper case and string concat
		Arrays
		.stream(strArray)
		.reduce((str1, str2) -> str1.toUpperCase() + " " + str2.toUpperCase())
		.ifPresent(System.out::println); // print to console


		// 1.4 String concatenation with pipe | separator
		Arrays
		.stream(strArray)
		.reduce((str1, str2) -> str1 + "|" + str2)
		.ifPresent(System.out::println); // print to console
	}
}

Output:

India is a Beautiful country

IndiaisaBeautifulcountry

INDIA IS A BEAUTIFUL COUNTRY

India|is|a|Beautiful|country

2.5 Throws NullPointerException when reduction is null

  • Stream’s reduce() method with one argument throws NullPointerException when result of reduction is null
  • Note: there is no possibility to provide initial value with this variant, therefore a better variant with initial/default value is discussed in the next section and this helps us to avoid NPE
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;

public class ExceptionInReduceAccumulator {

	public static void main(String[] args) {

		// String[] array
		String[] strArray =  {null};

		// string concatenate and print
		Arrays
		.stream(strArray)
		.reduce((str1, str2) -> str1 + " " + str2) // throws NPE
		.ifPresent(System.out::println);
	}
}

Output:

Exception in thread "main" java.lang.NullPointerException
	at java.util.Objects.requireNonNull(Objects.java:203)
	at java.util.Optional.<init>(Optional.java:96)
	at java.util.Optional.of(Optional.java:108)
	at java.util.stream.ReduceOps$2ReducingSink.get(ReduceOps.java:129)
	at java.util.stream.ReduceOps$2ReducingSink.get(ReduceOps.java:107)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
	at net.bench.resources.stream.reduce.example.ExceptionInAccumulator
.main(ExceptionInAccumulator.java:15)

3. Stream reduce() method with Identity and accumulator :

  • This is the second variant of the reduce() method which takes two arguments
    1. Identity as initial/default value
    2. BinaryOperator as accumulartor
  • Identity value will be used as a starting value while doing sum/multiply/subtraction/division operations
  • And the same Identity value will be used as a default value when Stream is empty
  • Note: by providing initial/default/starting value to the accumulator makes sure that reduce() won’t throw any exception like NullPointerException as in the case of 1st variant
  • Like 1st variant, this accumulator also perform reduction on the given Stream elements using Lambda expression or Method Reference
  • Method signature :- T reduce(T identity, BinaryOperator<T> accumulator)

3.1 Math operation with Stream elements providing initial value

  • We are going to perform Math operations like sum, subtract, multiply and divide using reduce() method by providing initial/start value
  • We can use either Lambda Expression or Method Reference for these Math operations
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;

public class MathOperationUsingReduceAccumulator {

	public static void main(String[] args) {

		// primitive int[] array
		int[] intArray = {
				17, 23, 29, 31, 37, 41, 43, 47, 53, 58
		};

		// 1.1 reduce() - sum using Method Reference
		int sum = Arrays
				.stream(intArray)
				.reduce(0, Integer::sum); // initial value 0

		System.out.println("Stream.reduce() - "
				+ "Sum with initial value 0 = " 
				+ sum);


		// 1.2 reduce() - subtract using Lambda Expression
		int subtract = Arrays
				.stream(intArray)
				.reduce(0, (m, n) -> m - n); // initial value 0

		System.out.println("Stream.reduce() - "
				+ "Subtract with initial value 0 = " 
				+ subtract);


		// 1.3 reduce() - multiply using Method Reference
		int multiply = Arrays
				.stream(intArray) // initial value 0
				.reduce(0, (m, n) -> m * n); // 0 multiply by whatever is 0

		System.out.println("Stream.reduce() - "
				+ "Multiply with initial value 0 = " 
				+ multiply);


		// 1.4 reduce() - division using Lambda Expression
		int division = Arrays
				.stream(intArray) // initial value 0
				.reduce(0, (m, n) -> m / n); // 0 divide by whatever is 0

		System.out.println("Stream.reduce() - "
				+ "Division with initial value 0 = " 
				+ division);
	}
}

Output:

Stream.reduce() - Sum with initial value 0 = 379
Stream.reduce() - Subtract with initial value 0 = -379
Stream.reduce() - Multiply with initial value 0 = 0
Stream.reduce() - Division with initial value 0 = 0

3.2 String concatenation of Stream elements providing default value

  • In this example, we are going to perform String concatenation operations using reduce() method by providing default value
  • We can use either Lambda Expression or Method Reference
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;

public class StringOperationUsingReduceAccumulator {

	public static void main(String[] args) {

		// initial value
		String defaultValue = null;

		// String[] array
		String[] strArray = {
				"is",
				"a",
				"Beautiful",
				"destination"
		};

		// 1.1 default value assigned
		defaultValue = "India";

		// 1.2 Stream.reduce() - string concatenation using lambda
		String strConcatIndia = Arrays
				.stream(strArray)
				.reduce(defaultValue, (str1, str2) -> str1 + " " + str2);

		System.out.println("String Concatention 1 = " + strConcatIndia);


		// 2.1 default value assigned
		defaultValue = "Dubai";

		// 2.2 Stream.reduce() - string concatenation using lambda
		String strConcatDubai = Arrays
				.stream(strArray)
				.reduce(defaultValue, (str1, str2) -> str1 + " " + str2);

		System.out.println("String Concatention 2 = " + strConcatDubai);
	}
}

Output:

String Concatention 1 = India is a Beautiful destination

String Concatention 2 = Dubai is a Beautiful destination

3.3 Returns default value when Stream is empty

  • When Stream is empty, then default/initial value is used for that particular operation using 2nd variant of reduce() method
  • In the below illustration, we have used 3 different examples to show reduction when Stream is empty
  • First, we are doing summation when Stream is empty and starting value is 1, so final sum is 1
  • Second, we are doing multiplication when Stream is empty providing initial value 1, so final result of multiplication is 1
  • Third, we are doing String concatenation when Stream is empty with default value ‘Australia’ and final string concatenation result is “Australia”
  • Note: nowhere we have faced any exception when we have provided default/initial/starting value in the reduce() method
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;

public class StreamIsEmpty {

	public static void main(String[] args) {

		// 1. empty primitive int array
		int[] intArrayEmpty = {};

		// 1.1 reduce() - sum using Method Reference
		int sum = Arrays
				.stream(intArrayEmpty)
				.reduce(1, Integer::sum); // initial value 1

		// 1.2 print to console
		System.out.println("Stream.reduce() - Sum on empty "
				+ "array with initial value 1 = " 
				+ sum);


		// 2.1 reduce() - multiply using Method Reference
		int multiply2 = Arrays
				.stream(intArrayEmpty)
				.reduce(1, (m, n) -> m * n); // initial value 1

		// 2.2 print to console
		System.out.println("Stream.reduce() - Multiply on empty "
				+ "array with initial value 1 = " 
				+ multiply2);


		// 3. empty String array
		String[] strArrayEmpty = {};

		// 3.1 default/initial value
		String defaultValue = "Australia";

		// 3.2 Stream.reduce() - string concatenation using lambda
		String result3 = Arrays
				.stream(strArrayEmpty)
				.reduce(defaultValue, (str1, str2) -> str1 + " " + str2);

		// 3.3 print to console
		System.out.println("String concatenation with "
				+ "initial value 'Australia' = " 
				+ result3);
	}
}

Output:

Stream.reduce() - Sum on empty array with initial value 1 = 1

Stream.reduce() - Multiply on empty array with initial value 1 = 1

String concatenation with initial value 'Australia' = Australia

3.4 Map and Reduce 1 – to find average Age of a class

  • A list contains 7 Student information with attributes like rollNo, name, and their age
  • Extract age from Student information using Stream’s map() method
  • And then we are going to reduce to get average age of class using Stream’s average() method which is one form of reduce() method

Student.java

package net.bench.resources.stream.reduce.example;

public class Student {

	// member variables
	private int rollNumber;
	private String name;
	private int age;

	// constructors

	// getters & setters

	// toString()
}

MapReduceOnStudentAverage.java

package net.bench.resources.stream.reduce.example;

import java.util.Arrays;
import java.util.List;

public class MapReduceOnStudentAverage {

	public static void main(String[] args) {

		// list of students
		List<Student> students = Arrays.asList(
				new Student(1, "Viraj", 17),
				new Student(2, "Krishnanand", 18),
				new Student(3, "Rishi", 19),
				new Student(4, "Suresh", 23),
				new Student(5, "Aditya", 22),
				new Student(6, "Rafat", 24),
				new Student(7, "Mandar", 21)
				);

		// print original Student list
		System.out.println("Original Student list :- \n");
		students.stream().forEach(System.out::println);

		// Stream.reduce() - to find Average age of class
		double averageAge = students
				.stream()
				.mapToInt(student -> student.getAge()) // map
				.average() // reduce
				.getAsDouble(); // return value as double

		System.out.format("\nThe average Age of class is = %.3f", averageAge);
	}
}

Output:

Original Student list :- 

Student [rollNumber=1, name=Viraj, age=17]
Student [rollNumber=2, name=Krishnanand, age=18]
Student [rollNumber=3, name=Rishi, age=19]
Student [rollNumber=4, name=Suresh, age=23]
Student [rollNumber=5, name=Aditya, age=22]
Student [rollNumber=6, name=Rafat, age=24]
Student [rollNumber=7, name=Mandar, age=21]

The average Age of class is = 20.571

3.5 Map and Reduce 2 – to find total amount of Grocery shopping

  • A list contains Product information of 4 grocery items, each with attributes like id, name, quantity and price
  • We are going to calculate amount of each items purchased by multiplying quantity with its price using Stream’s map() method
  • Finally, we are finding total amount of all items purchased using Stream’s reduce() method (via Method reference Double::sum)

Product.java

package net.bench.resources.stream.reduce.example;

public class Product {

	// member variables
	private int productId;
	private String productName;
	private int quantity;
	private double price;

	// 4 arg parameterized constructor

	// getters & setters

	// toString()
}

MapReduceOnStudentAverage.java

package net.bench.resources.stream.reduce.example;

import java.util.ArrayList;
import java.util.List;

public class MapReduceOnGroceryTotalPrice {

	public static void main(String[] args) {

		// list of products
		List<Product> products = new ArrayList<>();

		// add products to cart
		products.add(new Product(101, "Lentil", 4, 16.52)); // 4 lentil packets
		products.add(new Product(102, "Wheat", 2, 33.31)); // 2 wheat packets
		products.add(new Product(103, "Rice", 2, 55.69)); // 2 rice packets
		products.add(new Product(104, "Oil", 3, 165.27)); // 3 oil packets

		// print Product list
		System.out.println("Grocery shopping list :- \n");
		products.stream().forEach(System.out::println);

		// Stream.reduce() - to find total amount of shopping
		double totalAmount = products
				.stream()
				.map(product -> product.getPrice() * product.getQuantity()) // map
				.reduce(Double.MIN_VALUE, Double::sum); // reduce

		// total amount of shopping
		System.out.format("\nThe total shopping amount is = %.2f", 
				totalAmount);
	}
}

Output:

Grocery shopping list :- 

Product [productId=101, productName=Lentil, quantity=4, price=16.52]
Product [productId=102, productName=Wheat, quantity=2, price=33.31]
Product [productId=103, productName=Rice, quantity=2, price=55.69]
Product [productId=104, productName=Oil, quantity=3, price=165.27]

The total shopping amount is = 739.89

4. Stream reduce() method with Identity, accumulator and combiner :

  • This is the third variant of the reduce() method which takes three arguments
    1. Identity as initial/default value
    2. BiFunction as accumulartor
    3. BinaryOperator as combiner
  • This is mainly used in Parallel Stream
  • This is very much similar to 2nd variant except a combiner to combine the result when working in Parallel Stream
  • In Parallel Stream, streams are sub-divided into sub-streams and further computation/aggregate function are executed to achieve the target, so to combine the result we need combiner
  • Identity value will be used as a starting value for combiner
  • Method signature :- <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)

4.1 Math operation in Parallel Stream

  • First, we are going to calculate sum of all Stream elements with starting value of 0
  • Second, we are going to multiply all Stream elements with starting value of 1
  • We can use either Lambda Expression or Method Reference for these Math operations
package net.bench.resources.stream.reduce.example;

import java.util.Arrays;
import java.util.List;

public class ReduceWithParallelStream {

	public static void main(String[] args) {

		// List of Integers
		List<Integer> numbers = Arrays.asList( 
				10, 20, 30, 40, 50
				);

		// 1.1 reduce() - sum using combiner
		int sum = numbers
				.parallelStream() // parallel stream
				.reduce(0,  // initial value 0
						(x, y) -> x + y, // accumulator
						Integer::sum // combiner
						); 

		System.out.println("Parallel Stream reduce() - "
				+ "Sum with initial value 0 = " 
				+ sum);


		// 1.3 reduce() - multiply using combiner
		int multiply = numbers
				.parallelStream() // parallel stream
				.reduce(1, // initial value 1
						(m, n) -> m * n, // accumulator
						(A, B) -> A * B // combiner
						); 

		System.out.println("Parallel Stream reduce() - "
				+ "Multiply with initial value 1 = " 
				+ multiply);
	}
}

Output:

Parallel Stream reduce() - Sum with initial value 0 = 150

Parallel Stream reduce() - Multiply with initial value 1 = 12000000

5. Filter, Map and Reduce :

  • In this example, we are going to filter based on some criteria and then extract some value with map and finally reducing to get final desired value

5.1 Get total/average salary and count of employees working in IT department

  • A list of employees is defined with attributes like id, name, department and their salary
  • Filter – we are filtering to get employees of IT department
  • Map – extracting salary information from employee list after filtering
  • Reduce 1 – finding total salary of all IT department employees
  • Reduce 2 – finding count of IT department employees
  • Reduce 3 – finding average salary of IT department employees and returning double value to get accurate result with fractional portion

Employee.java

package net.bench.resources.stream.reduce.example;

public class Employee {

	// member variables
	private int id;
	private String name;
	private String department;
	private long salary;

	// 4 arg parameterized constructor

	// getters & setters

	// toString()
}

FilterMapReduceOnEmployeeSalaryAverage.java

package net.bench.resources.stream.reduce.example;

import java.util.Arrays;
import java.util.List;

public class FilterMapReduceOnEmployeeSalaryAverage {

	public static void main(String[] args) {

		// 1. list of employees
		List<Employee> employees = Arrays.asList(
				new Employee(101, "Krish", "IT", 87000),
				new Employee(102, "Viraj", "Admin", 62000),
				new Employee(103, "Suresh", "IT", 76000),
				new Employee(104, "Aditya", "IT", 81000),
				new Employee(105, "Rishi", "HR", 68000)
				);

		// 1.2 print original Student list
		System.out.println("Employees list :- \n");
		employees.stream().forEach(System.out::println);


		// 2. get TOTAL salary of IT employees
		long totalSalaryOfItEmp = employees
				.stream()
				.filter(employee -> employee.getDepartment()
						.equalsIgnoreCase("IT")) // filter
				.mapToLong(employee -> employee.getSalary()) // map
				.sum(); // reduce

		// 2.1 print to console
		System.out.println("\nThe Total salary of employees"
				+ " working in IT department is = " 
				+ totalSalaryOfItEmp);


		// 3. get COUNT of IT employees
		long countOfItEmp = employees
				.stream()
				.filter(employee -> employee.getDepartment()
						.equalsIgnoreCase("IT")) // filter
				.count(); // reduce

		// 3.1 print to console
		System.out.println("\nCount of employees"
				+ " working in IT department is = " 
				+ countOfItEmp);


		// 4. get AVERAGE salary of IT employees
		double average = employees
				.stream()
				.filter(employee -> employee.getDepartment()
						.equalsIgnoreCase("IT")) // filter
				.mapToLong(employee -> employee.getSalary()) // map
				.average() // reduce
				.getAsDouble(); // return double

		// 4.1 print to console
		System.out.println("\nThe average salary of employees"
				+ " working in IT department is = " 
				+ average);
	}
}

Output:

Employees list :- 

Employee [id=101, name=Krish, department=IT, salary=87000]
Employee [id=102, name=Viraj, department=Admin, salary=62000]
Employee [id=103, name=Suresh, department=IT, salary=76000]
Employee [id=104, name=Aditya, department=IT, salary=81000]
Employee [id=105, name=Rishi, department=HR, salary=68000]

The Total salary of employees working in IT department is = 244000

Count of employees working in IT department is = 3

The average salary of employees working in IT department is = 81333.33333333333

References:

Happy Coding !!
Happy Learning !!

Java 8 - Stream mapToInt() method
Java - How to print an Array