--> Top 31 Java 8 Interview Q & A » The Problem Solution

Top 31 Java 8 Interview Questions & Answers

Mastering Java 8 is essential for any modern Java developer. Our comprehensive guide covers the top 30 Java 8 interview questions and answers, focusing on key topics like lambda expressions, streams, functional interfaces, and the new APIs introduced in Java 8. Whether you’re preparing for interviews or aiming to deepen your understanding, this resource provides everything you need to excel in Java 8 development.

Java 8 image

1. Explain the new features in Java 8.

Java 8 introduced several significant features like,

  • lambda expressions
  • method reference
  • stream API
  • functional interface
  • default method in the interface
  • static method in the interface
  • new date and time API(JODA API)
  • optional class
  • new changes in base64 encryption decryption
  • collection API improvements

2. What is functional programming?

Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions. It emphasizes immutability, pure functions that always produce the same output for the same input without side effects, and avoids changing state or modifying data. In simple terms, it focuses on writing code that is modular, reusable, and easier to test by using functions as the main building blocks.

3. What is lambda expression in Java 8?

  • The lambda expression is an anonymous function that removes many boilerplate codes to make our program loosely coupled and speed up the process.
  • Most importantly, it only applies to functional interfaces with only one abstract method.

Syntax: (parameter) -> { expression or block of code }
Example:

// Before Java 8 (using an anonymous class)
Runnable r = new Runnable() {
    public void run() {
        System.out.println("Hello, World!");
    }
};

// Using Lambda expression in Java 8
Runnable r = () -> System.out.println("Hello, World!");

4. What is the functional interface in Java 8?

  • An interface that has only one abstract method within it is known as a functional interface.
  • But it can have 0 or more numbers of static and default methods.
  • Example: predicate, function, consumer, supplier, Runnable, Callable, Comparable.

5. Will it throw any error or exception, if we are not using @FuntionalInterface?

  • No, it is only a signal to JVM, if we are not using it, it is also ok.
  • But here is a case, if we are using it and that interface contains zero or more than 1 abstract method, only it will throw an exception.

6. What is the stream API in Java 8?

  • Stream API is a powerful tool for effectively processing Java collections.
  • It is a pipelining process consisting of intermediate operations, short-circuit operations and terminal operations.
  • The operations are, filter(), map(), reduce(), max(), min(), collect(), forEach() etc etc.
  • Example,
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// Using Stream API to filter even numbers and print them
numbers.stream()
       .filter(n -> n % 2 == 0)
       .forEach(s -> System.out.print(s + " - "));
       
// Output
// 1 - 2 - 3 - 4 - 5 -

7. What is method reference in Java 8?

  • Method reference is another way to represent lambda expression in Java. It makes the code more concise and readable by reusing methods that already exist.
  • Syntax: ClassName::methodName (if you remember it is scope resolution operator in C).
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

// Without method reference (using lambda)
list.forEach(item -> System.out.println(item));

// With method reference
list.forEach(System.out::println);

8. What are the types of method references in Java?

There are 3 types of method reference in Java,

  • Static method reference: ClassName::staticMethod
  • Instance method reference: instance::instanceMethod
  • Constructor reference: ClassName::new

9. What is the role of the default method in Java 8?

  • This allows new functionality to be added without hampering existing functionality.
  • In Java 8, default methods allow interfaces to have method implementations. This feature was introduced to enable backward compatibility, allowing developers to add new methods to interfaces without breaking existing implementations.

10. What is the need for static methods in Java?

  • In Java 8, static methods in interfaces allow you to define utility or helper methods directly in the interface. These methods can be called without creating an instance of the class, making code more organized and reusable.
  • Static methods in interfaces help group related functionality and avoid creating separate utility classes.
  • Example,
interface MyInterface {
    static void printMessage() {
        System.out.println("India Captain: Mahendra Singh Dhoni");
    }
}

MyInterface.printMessage(); // Call without instance

11. What is the need for optional classes in Java 8?

  • It helps avoid NullPointerException and provides a clearer way to represent the presence or absence of a value.
  • It provides methods to check if a value is present or not, reducing the need for explicit null checks.
  • By using it, you can make it clear that a value may or may not be present, improving code clarity and reducing errors.
  • You can specify default values to be used if the Optional is empty, making your code more robust.
  • In short, optional improves code readability, and maintainability, and reduces the risk of null-related errors.
Optional<String> optionalValue = Optional.of("India");
if (optionalValue.isPresent()) {
    System.out.println(optionalValue.get());
} else {
    System.out.println("No Value Found!!");
}

12. If we already have Date & Time then what is the need for a new Date & Time API in Java 8?

  • Time Zones: Handling time zones in the old API is difficult and error-prone. The new API provides dedicated classes and methods for working with time zones more easily and accurately.
  • Limited Functionality: The old API lacked functionalities like durations, periods, and clear formatting options. The new API offers a wider range of functionalities for various date and time operations.
  • Thread Safety: The old classes are not thread-safe, meaning they can cause issues when accessed by multiple threads concurrently. The new API uses immutable classes, making them thread-safe and avoiding concurrency problems.

13. Which functional interfaces have exactly one abstract method and what are they?

  • Function<T, R>: It takes one argument of type T and returns a value of type R.
  • Consumer<T>: It takes one argument of type T but doesn’t return anything.
  • Predicate<T>: It takes one argument of type T and returns a boolean value.
  • Supplier<T>: It takes any arguments but returns a value of type T.
  • UnaryOperator<T>: It takes and returns the same type (T) and operates on a single value.
  • BinaryOperator<T>: It takes and returns the same type (T) and operates on two arguments and combines them.

Example:

  • Function<String, Integer> stringToIntLength = (String str) -> str.length();
  • Consumer<String> printString = (String str) -> System.out.println(str);
  • Predicate<Integer> isEven = (int num) -> num % 2 == 0;
  • Supplier<String> randomStringSupplier = () -> UUID.randomUUID().toString();
  • UnaryOperator<Integer> increment = (num) -> num + 1;

14. What is the role of Predicate in Java 8?

  • It is a functional interface that represents a function that tests a condition and returns a boolean value. It is commonly used for filtering and evaluating conditions.
  • This makes filtering collections and building complex conditions in streams much easier.
Predicate<String> isNotEmpty = str -> !str.isEmpty();
boolean result = isNotEmpty.test("Hello"); // Returns true

15. Why do we need Function in Java 8?

  • It takes an input and produces an output. It is commonly used for transforming or mapping values.
  • It acts like a little factory. It doesn’t take anything (like an order), but it produces something (data) of a specific type.
  • This is helpful when you want to delay the creation of a value or make it more flexible based on your program’s needs.
Function<String, Integer> lengthFunction = str -> str.length();
int length = lengthFunction.apply("Hello"); // Returns 5

16. What is the purpose of forEach() method in Java 8?

  • It is a method used to iterate over elements in a collection or stream and perform an action on each element. It simplifies the process of applying operations to each item.
  • It internally uses Consumer to process the element.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name)); // Prints each name

17. What is the role of the Consumer?

  • It takes a single input and acts without returning a result. It’s commonly used for operations like printing or modifying elements.
  • Think of it this way: You give it some data (like a toy), it does something with it (plays with it), but doesn’t give you anything back.
  • ForEach() loop internally used consumer to iterate collection data in stream API.
Consumer<String> printConsumer = str -> System.out.println(str);
printConsumer.accept("Hello"); // Prints "Hello"

18. Why do we need a Supplier in Java 8?

  • It supplies or provides a value without taking any input. It’s often used for generating or retrieving values.
  • It acts like a little factory. It doesn’t take anything (like an order), but it produces something (data) of a specific type.
  • This is helpful when you want to delay the creation of a value or make it more flexible based on your program’s needs.
Supplier<String> stringSupplier = () -> "Hello, World!";
String value = stringSupplier.get(); // Returns "Hello, World!"

19. What is the parallel stream in Java 8?

  • A parallel stream allows you to process elements in a stream concurrently using multiple threads. It can improve performance for large datasets by leveraging multi-core processors.
  • It’s like having multiple lanes on a highway to move things faster. Or Imagine you have a big task to split up. A regular stream tackles it one piece at a time, like a single person. A parallel stream breaks it into chunks and assigns them to different workers (threads) to finish faster.
  • Here’s the key thing: parallel streams are good for tasks where the order you process things doesn’t matter. They can give your program a nice speed boost by taking advantage of your computer’s hardware.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.parallelStream()
       .map(n -> n * 2)
       .forEach(System.out::println); // Processes elements in parallel

20. What is the difference between a stream and a parallel stream 8?

  • Regular stream: Processes data from one element to another simultaneously, like a single worker. Good for simple tasks or when order matters. It is slower but good for any task (ordered or unordered).
  • Parallel Stream(): Splits the data into chunks and processes them simultaneously on multiple cores of your processor. Imagine having helpers in the kitchen, each doing a part of the recipe at the same time (if the recipe allows it 😅). It is faster (potentially), multi-threaded, and unordered.

Example:

  • Stream: list.stream().map(...)
  • Parallel Stream: list.parallelStream().map(...)

21. What are the different types of stream pipelines?

  • Streams take data from a source, transform it in stages, and then produce a result. It has different stages of pipelining to process the data.
  • Source: This is where your data comes from, like a list of numbers or lines from a file.
  • Intermediate Pipelines: Operations that transform a stream into another stream, such as map, filter, and sorted. They are lazy and do not process elements until a terminal operation is invoked.
  • Terminal Pipelines: Operations that produce a result or a side effect, such as collect, forEach, and reduce. They trigger the processing of the stream.

22. What are the intermediate operations in Java 8?

Intermediate operations are operations on a stream that transform it into another stream. They are lazy, meaning they are not executed until a terminal operation is performed. Here are some common intermediate operations:

  • filter(predicate): This operation keeps only the elements that match a specific condition.
  • map(function): This operation transforms each element in the stream into something else using a provided function.
  • flatMap(function): Works on streams of collections, and flattens them into a single stream of elements.
  • distinct(): Removes duplicate elements from the stream.
  • limit(n): Returns a stream with only the first n elements.
  • skip(n): This operation skips the first n elements in the stream and returns the remaining elements.
  • sorted(): This operation sorts the elements in the stream according to their natural ordering or a custom comparator function.
stream.filter(x -> x > 10);

stream.map(String::toUpperCase);

stream.distinct();

stream.limit(5);

stream.skip(3);

stream.sorted();

23. What are the terminal operations in Java 8?

Terminal operations are operations that produce a result or a side effect and trigger the processing of the stream. Once a terminal operation is invoked, the stream pipeline is executed.

  • forEach(consumer): This operation iterates through each element in the stream.
  • collect(supplier, accumulator, combiner): It gathers elements into a collection (like a list, set, or map) or performs a custom reduction.
  • reduce(BinaryOperator): This operation reduces all elements in the stream into a single element using a provided function. It’s like combining all elements into one value.
  • count(): This operation returns the total number of elements in the stream as a long value.
  • anyMatch(predicate): It checks if at least one element in the stream matches a given condition and then returns true, or false.
  • allMatch(predicate): Similar to anyMatch, this operation checks if all elements in the stream satisfy a specific condition and then returns true else returns false.
  • findFirst() / findAny(): Returns the first or any element that matches a condition. These are useful for finding specific elements without processing the entire stream.
  • toArray(Supplier): Converts the stream elements into an array of a specified type.
  • min(Comparator) / max(Comparator): Finds the minimum or maximum element according to a comparator function or natural ordering.
stream.forEach(System.out::println);

List<String> list = stream.collect(Collectors.toList());

int sum = stream.reduce(0, (a, b) -> a + b);

long count = stream.count();

boolean hasEven = stream.anyMatch(x -> x % 2 == 0);

boolean allPositive = stream.allMatch(x -> x > 0);

Optional<String> first = stream.findFirst();

Optional<String> any = stream.findAny();

String[] namesArray = list.stream().toArray(String[]::new);

Optional<Integer> min = numbers.stream().min(Comparator.naturalOrder());

Optional<Integer> max = numbers.stream().max(Comparator.naturalOrder());

24. What are the difference between map() and flatMap() in stream API?

  • map() is for one-to-one transformations. It applies a function to each element in the stream and produces one output element for each input element.
  • E.g, If you have a list of strings and want to get their lengths, you would use map().
  • flatMap() is for one-to-many transformations. It applies a function to each element in the stream, but the function can return zero, one, or multiple elements.
  • E.g, If you have a list of lists and want a single list of all elements, you would use flatMap().
List<String> words = Arrays.asList("Java", "Stream", "API", "Example");
List<Integer> lengths = words.stream()
                             .map(String::length)
                             .collect(Collectors.toList());
// lengths = [4, 6, 3, 7]

List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("Java", "Stream"),
    Arrays.asList("API", "Example")
);
List<String> allWords = listOfLists.stream()
                                   .flatMap(List::stream)
                                   .collect(Collectors.toList());
// allWords = [Java, Stream, API, Example]

25. How many ways you can create a stream in Java 8?

We can create a stream in several ways,

  • Collection: You can use the stream() method on any collection object (like List, Set, etc.) to create a stream of its elements.
  • Array: Similar to collections, you can use the stream() method on an array to create a stream of its elements.
  • Static methods: It provides static methods for creating streams in various scenarios: Stream.of(elements), Stream.empty(), Stream.builder().
  • Primitives: IntStream, LongStream, and DoubleStream for efficiency when dealing with primitive data types (int, long, double).
  • Infinite Streams: The Stream class provides methods for creating infinite streams: Stream.generate(supplier), Stream.iterate(seed, nextFunction).
  • String: You can create a stream of characters from a String using chars().
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();


String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);


Stream<String> stream = Stream.of("a", "b", "c");


Stream<Integer> stream = Stream.iterate(1, n -> n + 1).limit(5);
// Produces: 1, 2, 3, 4, 5


Stream<Double> stream = Stream.generate(Math::random).limit(5);
// Generates 5 random numbers


try (Stream<String> stream = Files.lines(Paths.get("file.txt"))) {
    // Process the stream
} catch (IOException e) {
    e.printStackTrace();
}

26. What is method chaining in Java 8?

In Java 8 (and before), method chaining is a way to call multiple methods on the same object, one after another, in a single line. Imagine you have an object like a car. Method chaining lets you call methods like startEngine() then .accelerate() then .moveSteering() all on the same car object, making the code more readable.

27. What is the difference between allMatch(), anyMatch(), and noneMatch()?

All three are methods used with streams in Java 8 to check if elements in the stream meet a certain condition. Imagine you have a box of colors and want to know which colors it has.

Condition is color = red.

  • allMatch(): It checks if all elements satisfy the condition or not. If the box contains all red colors then return true else if one color is not red then return false.
  • anyMatch(): It checks if at least one of them is red color then returns true else returns false.
  • nonmatch(): It checks if the box does not contain a red color and then returns true else false.

28. Can we reuse a stream object?

No, you cannot reuse a stream object in Java. Once a stream has been consumed or closed, it cannot be used again. Each stream can be used only once, and attempting to reuse it will result in an IllegalStateException.

But if you need to perform multiple operations on the same data, create a new stream each time. In this way, each stream is independently processed, and you avoid exceptions related to reusing streams.

29. What is the role of Collectors in Java 8?

Collectors provides various static methods to collect the elements of a stream into collections, aggregations, or other data structures. Common collectors include toList(), toSet(), and joining().

List<String> list = Arrays.asList("a", "b", "c");

List<String> result1 = list.stream().collect(Collectors.toList());

Set<String> result2 = list.stream().collect(Collectors.toSet());

String result3 = list.stream().collect(Collectors.joining(","));

30. What are IntStream, LongStream, and DoubleStream?

These are specialized stream types in Java 8 for handling primitive types (int, long, double). They offer additional methods for working with primitive values and avoiding boxing overhead.

IntStream intStream = IntStream.of(1, 2, 3, 4);
int sum1 = intStream.sum();

LongStream longStream = LongStream.of(1l, 2l, 3l, 4l);
long sum2 = longStream.sum();

DoubleStream doubleStream = DoubleStream.of(1.1, 2.2, 3.3, 4.4);
double sum3 = doubleStream.sum();

Leave a Reply

Your email address will not be published. Required fields are marked *