Java 8 Features Programming Interview Questions

Java 8 Features Programming Interview Questions
Java 8 Features Programming Interview Questions

Java 8 Features Programming Interview Questions

Java 8 Features Programming Interview Questions

1. Is it possible to implement two interfaces having default method with same name and signature?
This is the basic Java 8 Interview Questions asked in an interview. Consider the following code with implements two interfaces

public interface DefaultMethodInterface {
    default public void defaultMethod(){
        System.out.println("I am in Default method Interface I");
    }
}
public interface DefaultMethodInterface2 {
    default public void defaultMethod(){
        System.out.println("I am in Default method Interface II");
    }
}
public class HelloJava8 implements DefaultMethodInterface,DefaultMethodInterface2 {
    public static void main(String[] args){
        DefaultMethodInterface defMethIn = new HelloJava();
        defMethIn.defaultMethod();
    }
}

Here the compiler gives an error saying that “Duplicate Default Methods”. Hence it is not possible to implement two interfaces with the same name and signature.

2. Write a program to get the list of all students names from list of student

The Interviewer wants to know about the Collectors class and you use it efficiently with stream. Collectors.toList() will join all the results with delimiter specified in the parameter.

private static void joiningCollector(List<Student> students) {
 System.out.println("######## Executing joiningCollector() : ######## ");
 List<String> allStudentsNames = students.stream()
   .map(Student::getName)
   .collect(Collectors.toList());
 System.out.println("Collectors.toList() : "+allStudents);
 System.out.println("######## Ending the execution of joiningCollector() ######## "); 
}

3. Write a program to get all the students name comma seprated

Collectors.joining will join all the results with delimiter specified in the parameter.

private static void joiningCollector(List<Student> students) {
 System.out.println("######## Executing joiningCollector() : ######## ");
 String allStudents = students.stream()
   .map(Student::getName)
   .collect(Collectors.joining(" , "));
 System.out.println("Collectors.joining() : "+allStudents);
 System.out.println("######## Ending the execution of joiningCollector() ######## "); 
}

Output
######## Executing joiningCollector() : ########
Collectors.joining() : Saurabh , Robert , John , Roman , Randy
######## Ending the execution of joiningCollector() ########

4. Write a program to check if array contains the numbers less than 12

Here Interviewer checks your knowledge against the short circuit operation.

Below are the short circuit operators returns true or false value depending on the condition being evaluated.allMatch() – this will evaluate the condition for all the steams and will return a boolean value.
anyMatch() – this will evaluate the condition in the stream until it finds its match and once it finds the match, It will exit the processing and retruns the rboolean value.
noneMatch() – This is exact opposite of allMatch()
Lets see their behavior through some practical example.

int [] arr = {1,2,3,4,5,6,7,8,9,11};
    
System.out.println("All numbers are less than 12 : " + Arrays.stream(arr).allMatch(i-> i < 12));
System.out.println("Contains any numbers greater than 10 : " + Arrays.stream(arr).anyMatch(i-> i == 8));
System.out.println("All numbers are less than 10 : " + Arrays.stream(arr).noneMatch(i-> i > 10));
Output :
All numbers are less than 12 : true
Contains any numbers greater than 10 : true
All numbers are less than 10 : false

5. Write a program to get the minimum, maximum, average and total age of all the students object ?

summaryStatistics() method is used to calculate the sum, min, max, avg and total count of the elements passed to this method. In below example we are finding the sum, min, max of the Students age.
For more Info : https://www.onlyfullstack.com/advance-collectors-in-java-8/

private static void summaryStatisticsCollector(List<Student> students) {
 System.out.println("######## Executing summaryStatisticsCollector() : ######## ");
 DoubleSummaryStatistics statistics = students.stream()
   .mapToDouble(Student::getAge)
   .summaryStatistics();
 
 System.out.println("summaryStatistics() : "+statistics);
 System.out.println("Total Count : "+statistics.getCount());
 System.out.println("Total Sum : " + statistics.getSum());
 System.out.println("Minimum Age : " + statistics.getMin());
 System.out.println("Maximum Age : " + statistics.getMax());
 System.out.println("Average Age : " + statistics.getAverage());
 System.out.println("######## Ending the execution of summaryStatisticsCollector() ######## ");
}

Output
######## Executing summaryStatisticsCollector() : ########
summaryStatistics() : DoubleSummaryStatistics{count=5, sum=107.000000, min=17.000000, average=21.400000, max=26.000000}
Total Count : 5
Total Sum : 107.0
Minimum Age : 17.0
Maximum Age : 26.0
Average Age : 21.4
######## Ending the execution of summaryStatisticsCollector() ########

6. Find the students who lives are in Pune and who are not in Pune city.

We can partition a set of stream in two based on certain condition. So it will create two streams – one which satisfies the condition and another which does not satisfies the conditions.
Lets see below, suppose we want to divide the students who lives in Pune and who does not live in Pune.
partitioningBy will return a map containing two keys
true – which holds the stream which satisfy the condition.
false – which holds the stream which does not satisfy the condition.
For more Info : https://www.onlyfullstack.com/advance-collectors-in-java-8/

private static void partitioningByCollector(List<Student> students) {
 System.out.println("######## Executing partitioningByCollector() : ######## ");
 Map<Boolean,List<Student>> partition = students.stream()
   .collect(Collectors.partitioningBy(stud -> stud.getCity().equals("Pune")));
 
 System.out.println("Students living in Pune : "+partition.get(true));
 System.out.println("Students not living in Pune : "+partition.get(false));
 System.out.println("######## Ending the execution of partitioningByCollector() ######## ");
}

Output
######## Executing summaryStatisticsCollector() : ########
Students living in Pune : [Student [name=Saurabh, city=Pune, age=26], Student [name=Robert, city=Pune, age=25], Student [name=Roman, city=Pune, age=18]]
Students not living in Pune : [Student [name=John, city=Mumbai, age=21], Student [name=Randy, city=Mumbai, age=17]]
######## Ending the execution of summaryStatisticsCollector() ########

7. Group the student objects based on their city

partitioningBy() is very simple form of grouping the stream into two, but in real life we might need more than that. groupingBy() is used to group the stream based on the condition passed to the groupingBy(). In below example we are passing the city as an input to the groupingBy() which will split the stream into total number of cities available in the stream and will return a map as Map<String,List<Student>>.
For more Info : https://www.onlyfullstack.com/advance-collectors-in-java-8/

private static void groupingByCollector(List<Student> students) {
 System.out.println("######## Executing groupingByCollector() : ######## ");
 Map<String,List<Student>> groupBy = students.stream()
   .collect(Collectors.groupingBy(Student::getCity));
 
 System.out.println("groupingByCollector : "+groupBy);
 System.out.println("######## Ending the execution of groupingByCollector() ######## ");
}

Output
######## Executing groupingByCollector() : ########
groupingByCollector :
{Pune=[Student [name=Saurabh, city=Pune, age=26], Student [name=Robert, city=Pune, age=25], Student [name=Roman, city=Pune, age=18]],
Mumbai=[Student [name=John, city=Mumbai, age=21], Student [name=Randy, city=Mumbai, age=17]]}
######## Ending the execution of groupingByCollector() ########

8. Group the students name based on their city 
groupingBy() splits the stream into set of groups but it collects the complete object on which groupingBy is done. Like in above example of groupingBy(), we got the Map<String,List<Student>> where we gets the key as grouping factor and value as List<Student> objects, but what if we want to collect the names of Students or age of Students ? In this case mappingBy() comes into picture, mappingBy() allows us to pick the particular property of the Object to store into map rather than storing the complete Object.
For more Info : https://www.onlyfullstack.com/advance-collectors-in-java-8/

private static void mappingByCollector(List<Student> students) {
 System.out.println("######## Executing mappingByCollector() : ######## ");
 Map<String,Set<String>> mappingBy = students.stream()
   .collect(Collectors.groupingBy(Student::getCity, 
      Collectors.mapping(Student::getName, Collectors.toSet())));
 
 System.out.println("mappingByCollector : "+mappingBy);
 System.out.println("######## Ending the execution of mappingByCollector() ######## ");
}

Output
######## Executing mappingByCollector() : ########
mappingByCollector : {Pune=[Robert, Roman, Saurabh], Mumbai=[Randy, John]}
######## Ending the execution of mappingByCollector() ########

9. Write a program to explain how Streams are lazy?
How Intermediate operations are lazy?
We have a map() function in which we are printing the current student name. These names will only be printed if we apply a terminal operator to it. In below example we have applied the collect(terminal operator) and the map() prints the student names after the thread comes into running state. This is how intermediate operations works.
For more Info : https://www.onlyfullstack.com/intermediate-and-terminal-operations-of-stream-in-java-8/

private static void lazyIntermediateOperations(List<Student> students) throws InterruptedException {
 System.out.println("######## Executing lazyIntermediateOperations() : ######## ");
 Stream<String> studentStream = students.stream()
            .map(student -> {
           System.out.printf("In Map : %sn", student.getName());
           return student.getName().toUpperCase();
      });
 
 System.out.println("After map statement");
 Thread.sleep(5000);
 System.out.println("Thread is in Running state now");
 studentStream.collect(Collectors.toList());
 System.out.println("######## Ending the execution of lazyIntermediateOperations() ######## ");
}

Output
######## Executing lazyIntermediateOperations() : ########
After map statement
Thread is in Running state now
In Map : Saurabh
In Map : Robert
In Map : John
In Map : Roman
In Map : Randy
######## Ending the execution of lazyIntermediateOperations() ########