Java 8 Interview Questions


Java 8 Interview Questions

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

Java 8 Interview Questions
1. Why Java 8? What is the agenda behind Java 8?
  • The significant reason for introducing Java 8 was to introduce conciseness in the code.
  • Java brings in Functional programming which is enabled by Lambda Expressions (A powerful tool to create a concise code)
  • If you have ever observed, with python, scala we can do the same thing in very less Line of code (LOC). By mid-20s Java lost a large market due to these languages. To prevent further loss Java upgraded itself from only OOPS language to some concepts of Functional Programming to create a concise codebase.
2. What are the new features which got introduced in Java 8?
  1. Lambda Expression
  2. Functional Interfaces
  3. Default methods
  4. Static methods
  5. Double colon operator (::)
  6. Stream API
  7. Date and Time API
  8. Optional class
3. What are the main advantages of Java 8?
  1. Compact/Concise code (Less boilerplate code)
  2. More readable code and reusable code
  3. More testable code
  4. Parallel operations
4. What is a lambda expression?

Lambda expression is a new and important feature of Java that was included in Java 8. Lambda Expression is just an anonymous (nameless) function. That means the function which doesn’t have the name, return type, and access modifiers. Lambda Expression is also known as anonymous functions or closures.

public void add(inta, int b) {
   System.out.println(a+b);
}

We can write the above code in lambda expression as follows

(a, b) -> System.out.println(a+b);

E.g

package com.ashok.test;

import java.util.function.BiConsumer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class LambdaExpressionTest {
   public static void main(String[] args) {
      BiConsumer<Integer, Integer> consumer = (a, b) -> System.out.println(a + b);
      consumer.accept(10, 20);
   }
}
5. What are functional interfaces?
  • If an interface contains only one abstract method, such types of interfaces are called functional interfaces.
  • It can have any number of default methods and static methods.
  • There are many functional interfaces already present in java such as Runnable, Callable, Comparable, etc.
6. How are lambda expression and functional interfaces related?

Lambda expression provides the implementation of a functional interface.

Predicate<Integer> predicate = num -> num > 10;
System.out.println(predicate.test(5)); // false

Here

num -> num > 10                 ==> Lamda Expression
Predicate<Integer> predicate    ==> Functional interface
7. Can you create your own functional interface?
  • Yes we can create our own functional interface
  • As we know the functional interface is an interface with exactly one single abstract method and can have multiple default and static methods.
  • To create a functional interface
    • Create an interface
    • Annotate that with @FunctionalInterface
    • Define exactly one abstract method
    • There is no restriction on the number of default and static methods
  • Java can implicitly identify the functional interface but still, you can also annotate it with @FunctionalInterface. It just gives you the security that in case you by mistake add 2nd abstract method then the compiler will throw an Exception.
8. What is the method reference in Java 8?
  • Method reference is the replacement of lambda expression. It is used to refer the method of functional interface to an existing method. Mainly it is used for code reusability.
  • Functional interfaces abstract method can be mapped to the specified existing method using double colon operator (::). This is a method reference.
  • Hence method reference is an alternative to lambda expressions.
  • Whenever we have an existing implementation of the abstract method of our functional interface then we can go for method reference. If no such method implementation is available then go for lambda expression.
package com.ashok.java8.methodreference;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MethodReferenceTest {
   public static void main(String[] args) {
      Runnable r = MethodReferenceTest::m1;
      
      Thread t = new Thread(r);
      t.start();
      
      for (int i = 0; i < 10; i++) {
         System.out.println("Main Thread");
      }
   }

   private static void m1() {
      for (int i = 0; i < 10; i++) {
         System.out.println("Child Thread");
      }
   }
}
9. What default methods in Java 8?
  • The default method is a way of adding a new method in the existing interface without affecting the implemented classes. Hence with this new feature java, people defended many compile-time errors that may arise due to unimplemented methods of the interface.
  • The use of this default method is “Backword Compatibility” which means if JDK modifies any interface (Without the default method) then the classes which implement this interface will break.
package com.ashok.test;

/**
 * 
 * @author ashok.mariyala
 *
 */
interface Interf {
   default void m1(){ 
      System.out.println (“Hello..!! This is Default Method”); 
   }
}

class Test implements Interf { 
   public static void main(String[] args) { 
      Test t = new Test(); 
      t.m1();
   } 
}
10. Is it necessary to override default methods?
  • Default methods have dummy implementations
  • Implemented classes are Okay with dummy implementation then use the dummy implementation of default methods.
  • If not satisfied then they can override and provide their own implementation
11. Is the default keyword one of the access modifiers?
  • default is not the access modifier like a public or private or protected
  • If you are not used any access modifier then automatically that method is automatically default access modified (For default access modifier, we don’t use any keyword)
  • Hence default keyword is only used in classes till the 1.8 version for switch case only but never in the interface.
  • Now it is used for default methods in the interface to provide a default implementation for all implementing classes to use.
12. How to override the default methods?
  • You can override default methods by keeping the same method signature (name + arguments)
  • Removing default keywords because in class-default keyword is used in switch case to denote default case if no previous cases matched. So you can’t use the default keyword in class.
  • Adding public as access modifier because in interfaces by default all methods are public. So, in the child class, you can’t reduce the visibility of overridden default methods.
  • Finally giving our own implementation.
13. Can you use the hashCode() method default implementation in an interface?
  • You can’t give your default implementation of hashCode() in the interface for all implementing classes to use.
  • We are not allowed to override the Object class method as default methods in interface else will get a compile-time error.
  • All implementing classes by default have access to all methods of the object class.
  • An interface cannot provide a default implementation for any of the methods of the Object class.  In particular, this means one cannot provide a default implementation for equals, hashCode, or toString from within an interface.
  • Since all instances of interfaces are subclasses of Object, all instances of interfaces have non-default implementations of equals, hashCode, and toString already. Therefore, a default version of these on an interface is always useless, and it may as well not compile.
  • Another reason is that providing default implementations of these methods in an interface is most likely misguided. These methods perform computations over the object’s state, but the interface, in general, has no access to the state; only the implementing class has access to this state. Therefore, the class itself should provide the implementations, and default methods are unlikely to be useful.
14. How do default methods in interface cope-up with the diamond problem?
  • The diamond problem occurs in java due to multiple inheritances. If one class is extending 2 classes, and both of the classes have common methods then the child class will actually which method as its own? So it will be confusing between this parent 1 and parent 2. That is a diamond problem. That is why Java doesn’t allow multiple inheritance with classes.
  • Now coming to interfaces, If 2 implemented interfaces contain the same default methods then that’s the diamond problem.
  • In Java, in such a situation, the code will not compile. The solution for the diamond problem is
InterfaceName.super.methodName()
15 Why static methods are introduced in Java 8?
  • The only reason for introducing static methods in the interface is that you can call those methods with just interface names. No need to create a class and then its object.
  • Since an interface can never contain
    • Constructors
    • Static blocks
    • Nothing costly in terms of memory and performance.
  • Hence we don’t need to create objects and hence if you have everything static, then for interface rather than class.
  • You have this flexibility only after java 8, before that you need to create the class.
16 Are static methods are available to the implementing classes by default?
  • Static methods are not available to the implementing classes.
  • They are not default methods. They are static.
  • Hence you can call these methods using the interface name explicitly from the implementing classes as implementing classes won’t have access to these methods directly.
17. What are Predicates in Java 8?
  • A predicate is a predefined functional interface
  • The only abstract method of the predicate is test(T t);
public boolean test(T t);
  • Whenever we want to check some boolean conditions then you can go for Predicates.
Predicate<Integer> p = i -> (i >100);
System.out.println (p.test(150)); // true
18. What are the type parameter and return types of Predicates?
  • Input to predicate can be anything like
    • Predicate<String>
    • Predicate<Integer>
    • Predicate<Employee>
  • Hence only 1 type of argument is required which is the input type in Predicate.
  • The return type is not required as it’s always Boolean only.
19. Advantages of Predicates?
  • Code Reusability
  • If you have the same conditions being used 100 times in a program then you can write once and just use 100 times with checkLength.test(different string to be tested).
  • Conditional checks are held by Functional interfaces.
20. What is Predicate joining?

It’s possible to join predicates into a single predicate by using the following methods.

  • and()
  • or()
  • negate()

these are exactly the same as logical AND, OR, Complement operators.

import java.util.function.*; 
/**
 * 
 * @author ashok.mariyala
 *
 */
public class PredicateJoinTest { 
   public static void main(String[] args) {
      int[] x = {0, 5, 10, 15, 20, 25, 30}; 
      Predicate<Integer> p1 = i -> i>10;
      Predicate<Integer> p2 = i -> i%2==0;
      System.out.println("The Numbers Greater Than 10 :");
      m1(p1, x);
 
      System.out.println("The Even Numbers Are:");
      m1(p2, x);
   
      System.out.println("The Numbers Not Greater Than 10 :");
      m1(p1.negate(), x);
   
      System.out.println("The Numbers Greater Than 10 And Even Are :"); 
      m1(p1.and(p2), x);
   
      System.out.println("The Numbers Greater Than 10 OR Even : ");
      m1(p1.or(p2), x);
   }
   
   public static void m1(Predicate<Integer> p, int[] x) {
      for(int x1:x) {
         if(p.test(x1)) {
            System.out.println(x1);
         }
      }
   }
}
21. What are Functions in java 8?
  • A Function is a predefined functional interface
  • The only abstract method of the Function is apply(T t);
R apply(T t);
  • Given some input perform some operation on input and then product/return result (not necessary a boolean value)
  • This takes 1 input and returns one output.
  • In predicate we used to take 1 input and return type is always boolean.
  • In function, return is not fixed hence we declare both input type and return type.
package com.ashok.java8.function;

import java.util.function.Function;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class StringLengthFunction {
   public static void main(String[] args) {
      Function<String, Integer> f = s -> s.length();
      System.out.println(f.apply("Ashok Kumar")); // 11
   }
}
22. What are the differences between predicate and function?
Function vs Predicate
23. What is Function Chaining?

We can combine multiple functions together to form more complex functions. For this Function interface defines the following 2 default methods:

f1.andThen(f2)

Here, the first f1 will be applied and then for the result, f2 will be applied.

f1.compose(f2)

First, f2 will be applied and then for the result, f1 will be applied.

package com.ashok.java8.function;

import java.util.function.Function;
/**
 * 
 * @author ashok.mariyala
 *
 */
public class FunctionChainingTest {
   public static void main(String[] args) {
      Function<Integer, Integer> f1 = i -> i + i;
      Function<Integer, Integer> f2 = i -> i * i * i;
      
      System.out.println(f1.andThen(f2).apply(2)); // 64
      System.out.println(f1.compose(f2).apply(2)); // 16
   }
}
24. What is Consumer in java 8?
  • A Consumer is a predefined functional interface
  • Sometimes our requirement is we have to provide some input value, perform certain operations but are not required to return anything, then we should go for Consumer. i.e., the Consumer can be used to consume objects and perform certain operations. Consumer Functional Interface contains one abstract method.
public void accept(T t); 
package com.ashok.java8.consumer;

import java.util.function.Consumer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class ConsumerTest {
   public static void main(String[] args) {
      Consumer<String> c = s -> System.out.println(s);
      c.accept("Ashok Kumar"); // Ashok Kumar
   }
}
25. What is Consumer Chaining?
  • Just like Predicate Chaining and Function Chaining, Consumer Chaining is also possible. For this Consumer Functional Interface contains default method andThen().
c1.andThen(c2).andThen(c3).accept(s)
  • There is no compose method in the Consumer interface.
26. What is Supplier in java 8?
  • A Supplier is a predefined functional interface
  • The supplier will just supply required objects and it will not take any input.
  • It is always going to supply never consume/take any input.
  • There are no default and static methods in Supplier.
  • No chaining concept is available in the Supplier interface because no input is given to this. Only it gives you output.

E.g

  • Supply Random Name
  • Supply Random OTP
  • Supply Random Password etc
public R get(); 
package com.ashok.java8.supplier;

import java.util.function.Supplier;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class RandomOTP {
   public static void main(String[] args) {
      Supplier<String> otps = () -> {
         String otp = "";
         for (int i = 1; i <= 6; i++) {
            otp = otp + (int) (Math.random() * 10);
         }
         return otp;
      };
      System.out.println(otps.get());
      System.out.println(otps.get());
      System.out.println(otps.get());
      System.out.println(otps.get());
   }
}
27. What are the Steams in java 8?
  • If we want to process bulk objects of collection then go for the concept of the streams.
  • The stream API allows you to perform operations on collections without external iteration.
  • It is a special iterator class that allows processing collections of objects in a functional manner.

E.g

Fetch all objects from the collection of array list whose value is greater than 20.

public static List<Integer> findElements(List<Integer> arrayList) {
   List<Integer> newList = new ArrayList<>();
   for(Integer i : arrayList) {
      if(i >= 20) {
         newList.add(i);
      }
   }
   return newList;
}

With streams

public static List<Integer> findElements(List<Integer> arrayList) {
   List<Integer> newList = arrayList.stream().filter(num -> num >=20).collect(Collectors.toList());
}
28. What are the differences between Java.util.streams and Java.io streams?

java.util streams meant for processing objects from the collection. i.e, it represents a stream of objects from the collection but Java.io streams are meant for processing binary and character data with respect to files. i.e it represents a stream of binary data or character data from the file .hence Java.io streams and java.util streams both are different.

29. What is the difference between collection and stream?
  • If we want to represent a group of individual objects as a single entity then We should go for collection.
  • If we want to process a group of objects from the collection then we should go for streams.
  • We can create a stream object to the collection by using the stream() method of the Collection interface. stream() method is a default method added to the Collection in the 1.8 version.
30. How can you create and process a stream?
  • We can get the stream object by
Stream s = collectionObject.stream();
  • Once we got the stream, by using that we can process objects of that collection.
  • We can process the objects in the following 2 phases
    • Configuration
    • Processing
1. Configuration

We can configure either by using a filter mechanism or by using a map mechanism.

1. Filtering

We can configure a filter to filter elements from the collection based on some boolean conditions by using the filter() method of the Stream interface.

public Stream filter(Predicate<T> t);

E.g

list.stream().filter(i -> i%2==0).forEach(System.out.println());

Hence to filter elements of collection based on some Boolean condition we should go for the filter() method.

2. Mapping

If we want to create a separate new object, for every object present in the collection based on our requirement then we should go for the map() method of the Stream interface.

public Stream map (Function f);

E.g

list.stream().map(i -> i+5).forEach(System.out.println());
30. What is the difference between filter and map?
  • If we want to filter objects from the collection like filter only even numbers from the array list collection then use Filter for configuration of the stream.
  • If we want to perform some operation on each object of the collection then create another mapped object with a different value (after the operation is performed) for each object of that collection, then use the map.
  • In filter, because of filtering, the number of objects in the filtered list is less than the original list. While in Map same number of objects are there in both new and original list created.
31. What is the processing of the steam in java 8?

Once we performed configuration we can process objects by using several methods.

  • processing by collect() method
  • Processing by count()method
  • Processing by sorted()method
  • Processing by min() and max() methods
  • forEach() method
  • toArray() method
  • Stream.of()method
1. Processing by collect() method

This method collects the elements from the stream and adds to the specified to the collection indicated (specified) by argument.

List<Integer> evenNumList = list.stream().filter(i -> i%2==0).collect(Collectors.toList());

Set<String> upperCaseList = list.stream().map(str -> str.toUpperCase()).collect(Collectors.toSet());
2. Processing by count()method

If we want to count how many elements are there in the collection that satisfy a given condition then use the count() method.

long count = list1.stream().filter(str -> str.length() == 5).count();
3. Processing by sorted()method

If we sort the elements present inside the stream then we should go for the sorted() method. The sorting can either default natural sorting order or customized sorting order specified by the comparator.

1. sorted() : default natural sorting order
2. sorted(Comparator c) : customized sorting order.

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(5);
list.add(7);
list.add(21);
list.add(35);
List<Integer> sortedList = list.stream().sorted().collect(Collectors.toList()); // Default sorting

List<Integer> sortedList = list.stream().sorted((c1, c2) -> i2.compareTo(i1)).collect(Collectors.toList()); // Descending order
4. Processing by min() and max() methods
  • Min(Comparator) will return the minimum value based on the defined comparator
  • Max(Comparator) will return the maximum value based on the defined comparator
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(5);
list.add(7);
list.add(21);
list.add(35);
Integer min = list.stream().min((s1,s2) -> s1.compareTo(s2)).get();;
System.out.println(min); // 5
    
Integer max = list.stream().max((s1,s2) -> s1.compareTo(s2)).get();;
System.out.println(max); // 35
5. forEach() method

This method will not return anything. This method will take lambda expression as an argument and apply that lambda expression for each element present in the stream.

List<Integer> list = new ArrayList<>();
list.add(0);
list.add(15);
list.add(10);
list.add(5);
list.add(30);
list.add(25);
list.add(20);

list.stream().forEach(i -> System.out.println(i));
6. toArray() method

We can use the toArray() method to copy elements present in the stream into an array.

List<Integer> list = new ArrayList<>();
list.add(0);
list.add(15);
list.add(10);
list.add(5);
list.add(30);
list.add(25);
list.add(20);
Object[] ir = list.stream().toArray();
7. Stream.of() method
  • Stream concept is applicable for the collections and also applicable for any group of value.
  • Even for arrays, you can use stream.
  • Stream.of() method can take any group of values and convert them to stream. So that multiple stream operations can be applied to it.
 Stream stream = Stream.of(10, 20, 30, 40, 50);
 stream.forEach(num -> System.out.println(num));
 Double[] d = { 10.0, 10.1, 10.2, 10.3, 10.4};
 Stream stream1 = Stream.of(d);
 stream1.forEach(num -> System.out.println(num));
32. What are Java Parallel Streams?
  • Java Parallel Streams is a feature of Java 8 and higher, meant for utilizing multiple cores of the processor.
  • Normally any java code has one stream of processing, where it is executed sequentially. Whereas by using parallel streams, we can divide the code into multiple streams that are executed in parallel on separate cores and the final result is the combination of the individual outcomes. The order of execution, however, is not under our control.
  • Therefore, it is advisable to use parallel streams in cases where no matter what is the order of execution, the result is unaffected and the state of one element does not affect the other as well as the source of the data also remains unaffected.
Java Parallel Streams

Sequential Stream

List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
listOfNumbers.stream().forEach(number ->
    System.out.println(number + " " + Thread.currentThread().getName())
);

Output

1 main
2 main
3 main
4 main

Parallel Stream

List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4);
listOfNumbers.parallelStream().forEach(number ->
    System.out.println(number + " " + Thread.currentThread().getName())
);

Output

4 ForkJoinPool.commonPool-worker-3
2 ForkJoinPool.commonPool-worker-5
1 ForkJoinPool.commonPool-worker-7
3 main
Java 8 Interview Questions
Scroll to top