Java Interview Questions

Previous Java Interview Questions Next

Java 8 Features - Theory Questions

1. What are the main features introduced in Java 8?

Java 8 introduced several groundbreaking features: Lambda Expressions - enabling functional programming, Stream API - for bulk data operations, Default Methods in interfaces, Method References - shorthand for lambdas, Optional Class - for null-safe programming, New Date and Time API (java.time package), Nashorn JavaScript Engine, and Type Annotations. These features revolutionized Java programming towards functional style.

2. What are Lambda Expressions and what problems do they solve?

Lambda Expressions are anonymous functions that enable functional programming in Java. They provide a clear and concise way to represent instances of single-method interfaces (functional interfaces). Syntax: (parameters) -> expression or (parameters) -> { statements; }. They solve the problem of verbose anonymous class syntax, enable behavior parameterization, and facilitate parallel processing through functional programming paradigms.

3. What are Functional Interfaces in Java 8?

A Functional Interface is an interface with exactly one abstract method, annotated with @FunctionalInterface. Common examples include: Predicate<T> - boolean-valued function, Function<T,R> - transforms T to R, Consumer<T> - operates on T, Supplier<T> - provides T, and Runnable - no arguments, no result. Lambda expressions can be used to instantiate functional interfaces.

4. Explain the Stream API and its characteristics.

The Stream API provides a functional approach to process collections of objects. Key characteristics: Not a data structure - doesn't store data, Source-based - created from collections, arrays, I/O, Functional in nature - doesn't modify source, Lazy execution - intermediate operations are lazy, Parallelizable - can process elements in parallel. Stream operations are either intermediate (filter, map) or terminal (collect, forEach).

5. What are Default Methods in interfaces and why were they introduced?

Default Methods are methods in interfaces with implementation, using the default keyword. They were introduced to enable interface evolution without breaking existing implementations. When new methods are added to interfaces, existing implementing classes won't break as they inherit default implementations. This was crucial for adding new methods to Java Collections API without breaking backward compatibility.

6. What are Method References and what are their types?

Method References are shorthand notation for lambda expressions calling existing methods. Types include: Static method reference - ClassName::staticMethod, Instance method reference - instance::method, Arbitrary object method reference - ClassName::instanceMethod, and Constructor reference - ClassName::new. They make code more readable when lambda just calls an existing method.

7. What is the Optional class and how does it help with null handling?

The Optional class is a container object that may or may not contain a non-null value. It helps avoid NullPointerException by explicitly handling absence of value. Key methods: of(), ofNullable(), isPresent(), get(), orElse(), orElseGet(), orElseThrow(). It encourages developers to explicitly check for presence of value rather than assuming non-null, making code more robust and readable.

8. Explain the new Date and Time API (java.time package).

The java.time package introduced immutable, thread-safe date-time classes: LocalDate - date without time, LocalTime - time without date, LocalDateTime - date and time, ZonedDateTime - with timezone, Instant - machine-readable timestamp, Duration - time-based amount, and Period - date-based amount. It fixes issues with old Date and Calendar classes like mutability and poor API design.

9. What is the difference between intermediate and terminal operations in Streams?

Intermediate operations transform a stream into another stream (lazy evaluation). Examples: filter(), map(), sorted(), distinct(). They don't execute until a terminal operation is invoked. Terminal operations produce a result or side-effect and close the stream. Examples: forEach(), collect(), reduce(), count(). A stream pipeline must have exactly one terminal operation.

10. What are Collectors in Stream API?

Collectors are implementations of the Collector interface that implement various useful reduction operations. Common collectors: Collectors.toList(), Collectors.toSet(), Collectors.toMap(), Collectors.groupingBy(), Collectors.partitioningBy(), Collectors.joining(). They are used with the collect() terminal operation to accumulate elements into collections or other data structures.

11. What is the difference between map() and flatMap() in Streams?

map() transforms each element of a stream using a function, producing a one-to-one mapping. flatMap() transforms each element into a stream and then flattens all streams into a single stream, producing a one-to-many mapping. Example: map() converts List<String> to List<Integer> (lengths), while flatMap() converts List<List<String>> to List<String> by flattening nested lists.

12. What are Parallel Streams and when should they be used?

Parallel Streams enable parallel processing of stream elements using multiple threads. Created via parallelStream() or stream().parallel(). They should be used when: Processing large datasets, Operations are CPU-intensive, Order of processing doesn't matter, and No shared mutable state. However, they have overhead for thread management and should be avoided for small datasets or I/O-bound operations.

13. What is the "diamond problem" with multiple inheritance and how does Java 8 handle it?

The diamond problem occurs when a class implements multiple interfaces with the same default method. Java 8 handles this by: Requiring the implementing class to override the conflicting method, Using interfaceName.super.methodName() syntax to call specific interface's default method, or The compiler throws an error if the conflict isn't resolved. This ensures clear resolution of method conflicts.

14. What are the main functional interfaces in java.util.function package?

Key functional interfaces: Predicate<T> - boolean test(T t), Function<T,R> - R apply(T t), Consumer<T> - void accept(T t), Supplier<T> - T get(), UnaryOperator<T> - T apply(T t), BinaryOperator<T> - T apply(T t1, T t2). These cover most common use cases for lambda expressions.

15. What is the difference between forEach() and forEachOrdered() in Streams?

forEach() processes elements in encounter order for sequential streams, but order is not guaranteed for parallel streams. forEachOrdered() guarantees processing in encounter order even for parallel streams, though it may reduce parallelism benefits. Use forEach() when order doesn't matter (especially in parallel streams), and forEachOrdered() when order preservation is critical.

16. What are Static Methods in interfaces and how are they different from Default Methods?

Static methods in interfaces are similar to class static methods - they belong to the interface and cannot be overridden. They're called using interface name. Default methods are instance methods with implementation that can be overridden. Static methods provide utility methods related to the interface, while default methods provide default behavior for implementing classes.

17. What is the Nashorn JavaScript Engine?

Nashorn is a JavaScript engine developed in Java that replaced the older Rhino engine. It provides: Better performance through JVM optimizations, Full ECMAScript 5.1 compliance, Ability to execute JavaScript from Java code, and Java-JavaScript interoperability. However, note that Nashorn has been deprecated in later Java versions in favor of GraalVM.

18. What are Type Annotations and where can they be used?

Type Annotations extend the annotation syntax to allow annotations anywhere a type is used, not just declarations. They enable improved static code analysis and can be used with: Generic type arguments, Type casts, instanceof checks, method throws clauses, etc. This feature, combined with the Checker Framework, helps catch type-related errors at compile time.

19. What is the StringJoiner class and its benefits?

StringJoiner is a utility class for constructing sequences of characters separated by a delimiter. Benefits: Simplifies joining strings with delimiters, Supports prefix and suffix, Used internally by String.join() method. Example: StringJoiner sj = new StringJoiner(", ", "[", "]"); sj.add("A").add("B").add("C"); // Result: [A, B, C]

20. What are the performance considerations of Java 8 features?

Performance aspects: Lambda expressions - initially had overhead but improved with JVM optimizations, Streams - have overhead for small collections but excellent for large data, Parallel streams - thread management overhead, beneficial only for large CPU-intensive tasks, Method references - similar performance to lambdas, Optional - slight overhead but prevents costly null checks. Always profile before optimizing.

Previous Java Interview Questions Next