Top Java 8 Interview Questions You Must Know — Part-1
Hey dev’s ! , After going through several interview patterns in numerous companies, I’ve noticed that Java 8 features is hottest topic ever . Let’s break down the most common questions with examples you can actually understand and remember.
Q: What are Lambda Expressions and why should we use them?
lambdas are just shorthand for writing anonymous functions. They make your code cleaner and more readable.
// Old way (anonymous class)
// syntax is: (parameters) -> { body }
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked!");
}
});
// With Lambda
button.addActionListener(e -> System.out.println("Button clicked!"));
Q: What is a Functional Interface? Name some common ones.
It’s an interface with exactly one abstract method. You’ll use these a lot with lambdas.
// Common Functional Interfaces:
// Function: Takes one type, returns another
Function<String, Integer> length = str -> str.length();
// Predicate: Takes a value, returns boolean
Predicate<String> isEmpty = str -> str.isEmpty();
// Consumer: Takes a value, returns nothing
Consumer<String> printer = str -> System.out.println(str);
// Supplier: Takes nothing, returns a value
Supplier<String> getter = () -> "Hello World";
Q: How do you create a custom Functional Interface?
@FunctionalInterface // This annotation is optional but recommended
interface MathOperation {
int operate(int a, int b);
// Can have default methods
default void printInfo() {
System.out.println("Math Operation");
}
}
// Using it
MathOperation add = (a, b) -> a + b;
System.out.println(add.operate(5, 3)); // Outputs: 8
Q: What is Stream API and how is it different from collections?
Streams are for processing sequences of elements. Unlike collections, they:
- Don’t store data
- Can be infinite
- Are meant for operations like filter, map, reduce
// Common stream operations
List<String> names = Arrays.asList("John", "Jane", "Bob", "Alice");
// Filter and map example
List<String> longNames = names.stream()
.filter(name -> name.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
// Count, min, max examples
long count = names.stream()
.filter(name -> name.startsWith("J"))
.count();
Optional<String> shortest = names.stream()
.min(Comparator.comparing(String::length));
Q: What’s the difference between intermediate and terminal operations?
Want more detail check intermediate-terminal-operations-java-streams .
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Intermediate operations (lazy):
// - filter()
// - map()
// - sorted()
// Terminal operations (eager):
// - collect()
// - forEach()
// - count()
// This won't execute until there's a terminal operation
Stream<Integer> stream = numbers.stream()
.filter(n -> {
System.out.println("Filtering: " + n); // Won't print!
return n > 2;
});
// Now it executes
stream.forEach(n -> System.out.println("Foreach: " + n));
Q: Why was Optional introduced and how do you use it?
Optional helps prevent NullPointerException and makes code cleaner. it behaves like empty bucket .
// Before Optional
public String getUserEmail(User user) {
if (user != null) {
if (user.getEmail() != null) {
return user.getEmail();
}
}
return "default@email.com";
}
// With Optional
public String getUserEmail(User user) {
return Optional.ofNullable(user)
.map(User::getEmail)
.orElse("default@email.com");
}
// Common Optional operations
Optional<String> optional = Optional.of("value");
optional.isPresent() // Check if value exists
optional.isEmpty() // Check if empty (Java 11+)
optional.orElse("default") // Get value or default
optional.orElseThrow() // Get value or throw exception
Q: What are default methods and why were they added?
Default methods let you add new methods to interfaces without breaking existing implementations.
// Original interface many teams are using
interface Notifier {
void sendNotification(String message);
// New requirement cames : Add logging without breaking existing code
default void sendWithLogging(String message) {
System.out.println("Sending: " + message);
sendNotification(message);
System.out.println("Sent successfully");
}
// Another new requirement: Add retry capability
default void sendWithRetry(String message, int maxAttempts) {
int attempts = 0;
while (attempts < maxAttempts) {
try {
sendNotification(message);
return;
} catch (Exception e) {
attempts++;
System.out.println("Attempt " + attempts + " failed");
}
}
throw new RuntimeException("Failed after " + maxAttempts + " attempts");
}
}
// Existing implementation - still works!
class EmailNotifier implements Notifier {
@Override
public void sendNotification(String message) {
// Send email logic
System.out.println("Email sent: " + message);
}
}
// New implementation - can override default behavior
class SlackNotifier implements Notifier {
@Override
public void sendNotification(String message) {
// Send Slack message
System.out.println("Slack message: " + message);
}
// Custom logging implementation
@Override
public void sendWithLogging(String message) {
System.out.println("Slack channel: #general");
System.out.println("Timestamp: " + System.currentTimeMillis());
sendNotification(message);
System.out.println("Slack message delivered");
}
}
// Usage
public class NotificationExample {
public static void main(String[] args) {
Notifier emailNotifier = new EmailNotifier();
Notifier slackNotifier = new SlackNotifier();
// Using default implementation
emailNotifier.sendWithLogging("Hello via email");
// Output:
// Sending: Hello via email
// Email sent: Hello via email
// Sent successfully
// Using custom implementation
slackNotifier.sendWithLogging("Hello via Slack");
// Output:
// Slack channel: #general
// Timestamp: 1234567890
// Slack message: Hello via Slack
// Slack message delivered
// Using default retry mechanism
emailNotifier.sendWithRetry("Important email", 3);
}
}
When asked about default methods, mentioning backward compatibility and interface evolution makes you sound like you understand the bigger picture, not just the syntax.
Practice Questions
Try these:
- Write a stream pipeline to find the average of all even numbers in a list
- Create a custom functional interface and use it with a lambda
- Implement a method chain using Optional to handle null checks
Hope this helps with your interview prep ! What feature would you like me to cover in detail next ?
Follow for more interview preparation guides !