Java 8 Advanced Interview Questions


Java 8 Advanced Interview Questions

This tutorial would walk you through the Java 8 advanced interview questions for freshers and experienced, scope, and opportunities.

Java 8 Advanced Interview Questions
1. What is an intermediate operation in streams?

The operations which return another stream, as a result, are called intermediate operations.

E.g

filter(), map(), distinct(), sorted(), limit(), skip()
2. Why java streams are lazy?

Streams are lazy because intermediate operations are not evaluated unless the terminal operation is invoked. Each intermediate operation creates a new stream, stores the provided operation/function, and returns the new stream.

3. What is a terminal operation in streams?
  • The operations which return non-stream values like primitive or object or collection or nothing are called terminal operations.
  • You can chain multiple intermediate operations and none of them will do anything until you invoke a terminal operation. At that time. all of the intermediate operations that you invoked earlier will be invoked along with the terminal operation.

E.g

forEach(), toArray(), collect(), min(), max(), count(), etc.
4. What is a peek() method in java 8?
  • The steam peek() method is an intermediate operation
  • It takes a consumer object as an input.
  • It returns a stream consisting of the elements of the current stream.
  • It additionally performs the provided action on each element.
  • peek() exists mainly to support debugging, where we want to see the elements as they flow past a certain point in the pipeline.
  • It is similar to Map, but it takes a consumer object and performs some action on the object and returns nothing, but a map takes a function argument hence apply the operation on each element and returns the stream having modified elements.
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.stream().peek( System.out::println );   //prints nothing

List<Integer> newList = list.stream().peek(System.out::println).collect(Collectors.toList());
System.out.println(newList);

1
2
3
4
5
[1, 2, 3, 4, 5]
5. Count the number of occurrences of words in a given string using Java 8?

Input: “welcome to waytoeasylearn and waytoeasylearn welcome you”

Output: [welcome=2, and=1, to=1, waytoeasylearn=2, you=1]

package com.ashok.test;

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * 
 * @author ashok.mariyala
 *
 */
public class NumberOfOccurrences {
	public static void main(String[] args) {
		String input = "welcome to waytoeasylearn and waytoeasylearn welcome you";
		String[] inputArray = input.split(" ");
		Map<String, Long> occurrencesMap = Stream.of(inputArray)
				.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
		System.out.println(occurrencesMap);
	}
}

Output

{waytoeasylearn=2, and=1, to=1, welcome=2, you=1}
5. Find the duplicate elements in a given integers list in java using streams?
package com.ashok.test;

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * 
 * @author ashok.mariyala
 *
 */
public class NumberOfOccurrences {
   public static void main(String[] args) {
      List<Integer> numList = Arrays.asList(5, 9, 1, 4, 1, 3, 9);
      Set<Integer> numSet = new HashSet<>();
      numList.stream().filter(num -> !numSet.add(num)).forEach(System.out::println);
   }
}

Output

1
9
6. What is the difference between the limit () and skip() method and explain with an example?

Limit: The limit(n) method is an intermediate operation that returns a stream not longer than the requested size. As before, the n parameter can’t be negative.

Skip: The skip(n) method is another intermediate operation that discards the first n elements of a stream. The n parameter can’t be negative. and if it’s higher than the size of the stream. skip() returns the empty stream.

package com.ashok.test;

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

/**
 * 
 * @author ashok.mariyala
 *
 */
public class TestLimitAndSkip {
	public static void main(String[] args) {
		List<Integer> intList = Arrays.asList(2, 5, 7, 8, 9, 4, 3, 11, 14, 18, 20, 24);
		intList.stream().limit(5).forEach(System.out::println);
		System.out.println("=============");
		intList.stream().skip(5).forEach(System.out::println);
	}
}

Output

2
5
7
8
9
=============
4
3
11
14
18
20
24
6. Check the given number is prime or not using java 8?
package com.ashok.test;

import java.util.stream.IntStream;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class PrimeOrNot {
	public static void main(String[] args) {
		System.out.println(isPrime(6));
		System.out.println(isPrime(11));
	}

	private static boolean isPrime(int number) {
		return number > 1 && IntStream.range(2, number).noneMatch(n -> number % n == 0);
	}
}

Output

false
true
7. What is the difference between Map and FlatMap in java 8?

Let’s assume that we have a list of employees and we need to get the list of cities where they have worked in past years.

How does Map work?

  • The Stream.map() function performs map functional operation. i.e, it takes a Stream and transforms it into another new Stream.
  • It applies a function on each element of Stream and stores return value into new Strem.
  • The map operation takes a Function. which is called for each value in the input stream and produces one result value, which is sent to the output stream.

How does FlatMap work?

  • It is a combination of a map and a flat operation.
  • This means you first apply the map function and then flattens the results.
  • The key difference is the function used by map operation returns a stream of values or a list of values rather than a single value. That’s why we need flattening. When you flat a stream of stream, it gets converted into a stream of values.
  • To understand what flattening a stream consists of, consider a structure like [[1,2,3],[4,5,6],[7,8,9]] which had “two levels”. It is basically a big list containing 3 more lists. Flattening this means transforming it into a “one level” structure. E.g [1,2,3,4,5,6,7,8,9] i.e., just one list.
package com.ashok.test;

import java.util.List;

public class Employee {
	private String empId;
	private String empName;
	private List<String> citiesWorkedIn;

	public String getEmpId() {
		return empId;
	}

	public void setEmpId(String empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}
	
	public List<String> getCitiesWorkedIn() {
		return citiesWorkedIn;
	}

	public void setCitiesWorkedIn(List<String> citiesWorkedIn) {
		this.citiesWorkedIn = citiesWorkedIn;
	}
}
package com.ashok.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MapAndFlatMap {
	public static void main(String[] args) {
		Employee ashok = new Employee("E0087", "Ashok Kumar", Arrays.asList("Bhimavaram", "Hyderabad"));
		Employee vinod = new Employee("38024591", "Vinod Kumar", Arrays.asList("Chennai", "Hyderabad", "Banglore"));
		Employee rama = new Employee("5221188", "Srirama", Arrays.asList("Chennai", "Mumbai", "Banglore", "Pune"));

		List<Employee> empList = new ArrayList<>();
		empList.add(ashok);
		empList.add(vinod);
		empList.add(rama);
		
		empList.stream().map(emp -> emp.getEmpId()).collect(Collectors.toSet());
		
		Set<List<String>> citiesWorkedIn = empList.stream().map(emp -> emp.getCitiesWorkedIn()).collect(Collectors.toSet());
		System.out.println(citiesWorkedIn);
		
		Set<String> citiesWorkedInFlatten = empList.stream().flatMap(emp -> emp.getCitiesWorkedIn().stream()).collect(Collectors.toSet());
		System.out.println(citiesWorkedInFlatten);
	}
}

Output

[[Chennai, Mumbai, Banglore, Pune], [Bhimavaram, Hyderabad], [Chennai, Hyderabad, Banglore]]
[Banglore, Chennai, Pune, Bhimavaram, Mumbai, Hyderabad]
8. What is an Optional class in java 8?
  • Java Optional class provides a way to deal with null values. It is used to represent a value is present or not. Java 8 added a new class Optional available in java.util package.
  • A NullpointerException is a common issue in java applications. To prevent this, we normally add frequent null checks in our code to check if a variable is not empty before we use it in our program. The Optional class provides a better approach to handling such situations.
  • You can view Optional as a single-value container that either contains a value or doesn’t (it is then said to be “empty”)
  • get() method only returns a value if the wrapped object is not null. Otherwise, it throws a no such element exception.
  • This is the major flaw of the get() method. Ideally, Optional should help us avoid such unforeseen exceptions. Therefore, this approach works against the objectives of Optional and will probably be deprecated in a future release.
  • When we have an Optional object returned from a method or created by us, we can check if there is a value in it or not with the isPresent() method.
  • This method returns true if the wrapped value is not null.
Optional<Student> studentDetails = studentRepository.findById(studentId);
if (studentDetails.isPresent()) {
   Student student = studentDetails.get();
   return student;
} else {
   throw new StudentNotfoundException("No student found with given student id. Nothing to display");
}
9. How to create an Optional class in java 8?
  • We can create an Optional object with Optional’s static method – Of()
  • The argument passed to the Of() method can’t be null. Otherwise, we’ll get a NullPointerException
  • But in case we expect some null values, we can use the ofNullable() method.
  • By doing this, if we pass in a null reference, it doesn’t throw an exception but rather returns an empty Optional object.
Optional<Student> studentDetails = studentRepository.findById(studentId);
if (studentDetails.isPresent()) {
   Optional<String> name = Optional.ofNullable(student.get().getName());
   if (name.isPresent()) {
      studentName = name.get()
   }
   return studentName;
} else {
   throw new StudentNotfoundException("No student found with given student id. Nothing to display");
}
10. Given an employee list, sort employees based on their salaries in descending order?
package com.ashok.test;

import java.util.List;

public class Employee {
	private String empId;
	private String empName;
	private List<String> citiesWorkedIn;
	private int salary;

	public Employee(String empId, String empName, int salary) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.salary = salary;
	}

	public Employee(String empId, String empName, List<String> citiesWorkedIn) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.citiesWorkedIn = citiesWorkedIn;
	}

	public String getEmpId() {
		return empId;
	}

	public void setEmpId(String empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	public List<String> getCitiesWorkedIn() {
		return citiesWorkedIn;
	}

	public void setCitiesWorkedIn(List<String> citiesWorkedIn) {
		this.citiesWorkedIn = citiesWorkedIn;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}

	@Override
	public String toString() {
		return "[empId=" + empId + ", empName=" + empName + ", salary=" + salary + "]";
	}
}
package com.ashok.test;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class EmployeeSalaryTest {
	public static void main(String[] args) {
		List<Employee> empList = new ArrayList<>();
		empList.add(new Employee("001", "Ashok Kumar", 52000));
		empList.add(new Employee("002", "Vinod Kumar", 83000));
		empList.add(new Employee("003", "Ram Kumar", 215200));
		empList.add(new Employee("004", "Lakshman Kumar", 135000));
		empList.add(new Employee("005", "Bharath Kumar", 23000));
		empList.add(new Employee("006", "Sarath Kumar", 48000));
		empList.add(new Employee("007", "Seetha", 48000));
		empList.add(new Employee("008", "Anji Kumar", 93000));
		empList.add(new Employee("009", "Naresh Kumar", 72000));

		List<Employee> empSortedList = empList.stream().sorted((obj1, obj2) -> (obj2.getSalary() - obj1.getSalary())).collect(Collectors.toList());
		System.out.println(empSortedList);
	}
}

Output

[[empId=003, empName=Ram Kumar, salary=215200], [empId=004, empName=Lakshman Kumar, salary=135000], [empId=008, empName=Anji Kumar, salary=93000], [empId=002, empName=Vinod Kumar, salary=83000], [empId=009, empName=Naresh Kumar, salary=72000], [empId=001, empName=Ashok Kumar, salary=52000], [empId=006, empName=Sarath Kumar, salary=48000], [empId=007, empName=Seetha, salary=48000], [empId=005, empName=Bharath Kumar, salary=23000]]
11. Fetch the top 3 salaried employees?
package com.ashok.test;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class EmployeeSalaryTest {
	public static void main(String[] args) {
		List<Employee> empList = new ArrayList<>();
		empList.add(new Employee("001", "Ashok Kumar", 52000));
		empList.add(new Employee("002", "Vinod Kumar", 83000));
		empList.add(new Employee("003", "Ram Kumar", 215200));
		empList.add(new Employee("004", "Lakshman Kumar", 135000));
		empList.add(new Employee("005", "Bharath Kumar", 23000));
		empList.add(new Employee("006", "Sarath Kumar", 48000));
		empList.add(new Employee("007", "Seetha", 48000));
		empList.add(new Employee("008", "Anji Kumar", 93000));
		empList.add(new Employee("009", "Naresh Kumar", 72000));

		List<Employee> empSortedList = empList.stream().sorted((obj1, obj2) -> (obj2.getSalary() - obj1.getSalary())).limit(3).collect(Collectors.toList());
		System.out.println(empSortedList);
	}
}

Output

[[empId=003, empName=Ram Kumar, salary=215200], [empId=004, empName=Lakshman Kumar, salary=135000], [empId=008, empName=Anji Kumar, salary=93000]]
12. Fetch all employees having salaries less than the 3rd highest salary?
package com.ashok.test;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class EmployeeSalaryTest {
	public static void main(String[] args) {
		List<Employee> empList = new ArrayList<>();
		empList.add(new Employee("001", "Ashok Kumar", 52000));
		empList.add(new Employee("002", "Vinod Kumar", 83000));
		empList.add(new Employee("003", "Ram Kumar", 215200));
		empList.add(new Employee("004", "Lakshman Kumar", 135000));
		empList.add(new Employee("005", "Bharath Kumar", 23000));
		empList.add(new Employee("006", "Sarath Kumar", 48000));
		empList.add(new Employee("007", "Seetha", 48000));
		empList.add(new Employee("008", "Anji Kumar", 93000));
		empList.add(new Employee("009", "Naresh Kumar", 72000));

		List<Employee> empSortedList = empList.stream().sorted((obj1, obj2) -> (obj2.getSalary() - obj1.getSalary())).skip(3).collect(Collectors.toList());
		System.out.println(empSortedList);
	}
} 

Output

[[empId=002, empName=Vinod Kumar, salary=83000], [empId=009, empName=Naresh Kumar, salary=72000], [empId=001, empName=Ashok Kumar, salary=52000], [empId=006, empName=Sarath Kumar, salary=48000], [empId=007, empName=Seetha, salary=48000], [empId=005, empName=Bharath Kumar, salary=23000]]
13. Java 8 statistics example: Get count, sum, min, max, and the average of the numbers?
  • Given employee database, fetch max salaried employee, min salaried employee, find the average salary of all employees working in an organization, etc.
  • stream().mapToInt(num -> num).summaryStatistics();
  • Since these statistics operations are numeric in nature, it’s essential to call the mapToInt() method.
  • It provides us utility method like getMin(), getMax(), getSum() or getAverage().
  • By using these general-purpose methods, you can easily do a lot of things that require a lot of code before Java 8.
package com.ashok.test;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class EmployeeSalaryTest {
	public static void main(String[] args) {
		List<Employee> empList = new ArrayList<>();
		empList.add(new Employee("001", "Ashok Kumar", 52000));
		empList.add(new Employee("002", "Vinod Kumar", 83000));
		empList.add(new Employee("003", "Ram Kumar", 215200));
		empList.add(new Employee("004", "Lakshman Kumar", 135000));
		empList.add(new Employee("005", "Bharath Kumar", 23000));
		empList.add(new Employee("006", "Sarath Kumar", 48000));
		empList.add(new Employee("007", "Seetha", 48000));
		empList.add(new Employee("008", "Anji Kumar", 93000));
		empList.add(new Employee("009", "Naresh Kumar", 72000));

		List<Integer> empSalaryList = empList.stream().map(emp -> emp.getSalary()).collect(Collectors.toList());
		int maximumSalary = empSalaryList.stream().mapToInt(num -> num).summaryStatistics().getMax();
		System.out.println("Maximum Salary : " + maximumSalary);

		int minimumSalary = empSalaryList.stream().mapToInt(num -> num).summaryStatistics().getMin();
		System.out.println("Minimum Salary : " + minimumSalary);
		
		long totalSalary = empSalaryList.stream().mapToInt(num -> num).summaryStatistics().getSum();
		System.out.println("Total Salary : " + totalSalary);
		
		double averageSalary = empSalaryList.stream().mapToInt(num -> num).summaryStatistics().getAverage();
		System.out.println("Average Salary : " + averageSalary);
	}
}

Output

Maximum Salary : 215200
Minimum Salary : 23000
Total Salary : 769200
Average Salary : 85466.66666666667
14. What is Java 8 Stream Collectors groupingBy?

Given a stream of objects, there are scenarios where these objects need to be grouped based on a certain distinguishing characteristic they possess.

E.g

Create a map with key as age and value as a list of employees in that age group.

  • This concept of grouping is the same as the ‘group by’ clause in SQL which takes an attribute, or a calculated value derived from attribute(s), to divide the retrieved records into distinct groups.
  • Generally what we used to do in the group by is
  • Iterating over each object, checking with the group the object being examined falls in, and then adding that object to its correct group. The group itself is held together using a Collection instance.
package com.ashok.test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GroupingByTest {

	public static void main(String[] args) {
		List<Employee> empList = new ArrayList<>();
		empList.add(new Employee("001", "Ashok Kumar", 30));
		empList.add(new Employee("002", "Vinod Kumar", 32));
		empList.add(new Employee("003", "Ram Kumar", 35));
		empList.add(new Employee("004", "Lakshman Kumar", 31));
		empList.add(new Employee("005", "Bharath Kumar", 29));
		empList.add(new Employee("006", "Sarath Kumar", 30));
		empList.add(new Employee("007", "Seetha", 31));
		empList.add(new Employee("008", "Anji Kumar", 32));
		empList.add(new Employee("009", "Naresh Kumar", 29));

		Map<Object, List<Employee>> empAgeMap = empList.stream().collect(Collectors.groupingBy(emp -> emp.getAge()));
		empAgeMap.forEach((k, v) -> System.out.println("Key : " + k + ", Value : " + v));

	}

}

Output

Key : 32, Value : [[empId=002, empName=Vinod Kumar, Age=32], [empId=008, empName=Anji Kumar, Age=32]]
Key : 35, Value : [[empId=003, empName=Ram Kumar, Age=35]]
Key : 29, Value : [[empId=005, empName=Bharath Kumar, Age=29], [empId=009, empName=Naresh Kumar, Age=29]]
Key : 30, Value : [[empId=001, empName=Ashok Kumar, Age=30], [empId=006, empName=Sarath Kumar, Age=30]]
Key : 31, Value : [[empId=004, empName=Lakshman Kumar, Age=31], [empId=007, empName=Seetha, Age=31]]
Java 8 Advanced Interview Questions
Scroll to top