Java 8 introduced several new features and enhancements to the language, focusing on improving code readability, conciseness, and support for functional programming. Here are some key features with examples:
1. Lambda Expressions
Lambda expressions introduce a concise way to express instances of single-method interfaces (functional interfaces). They improve the readability of code, especially when working with functional interfaces.
For more explanation Lambda Expression
Example:
// Before Java 8
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Running the old way!");
}
};
// Java 8 with Lambda
Runnable lambdaRunnable = () -> System.out.println("Running with Lambda!");
2. Functional Interfaces
Functional interfaces are interfaces with a single abstract method. They enable the use of lambda expressions for concise and expressive code.
Example:
// Predefined Functional Interface: Runnable
Runnable myRunnable = () -> System.out.println("Executing...");
// Custom Functional Interface
@FunctionalInterface
interface MyFunctionalInterface {
void myMethod();
}
MyFunctionalInterface myFunction = () -> System.out.println("My custom method.");
3. Streams API
The Streams API provides a powerful and expressive way to manipulate collections of data, supporting operations like filter, map, reduce, and more.
Example:
List<String> myList = Arrays.asList("Apple", "Banana", "Orange", "Grapes");
// Using Stream API to filter and print
myList.stream()
.filter(fruit -> fruit.startsWith("A"))
.forEach(System.out::println);
4. Default Methods
Default methods allow interface authors to add new methods to interfaces without breaking backward compatibility.
Example:
interface MyInterface {
void existingMethod();
default void newMethod() {
System.out.println("Default implementation of newMethod");
}
}
class MyClass implements MyInterface {
@Override
public void existingMethod() {
System.out.println("Implementing existingMethod");
}
}
// Using default method
MyClass myObject = new MyClass();
myObject.existingMethod();
myObject.newMethod();
5. Method References
Method references provide a shorthand syntax for lambda expressions to call methods.
Example:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// Using lambda expression
names.forEach(name -> System.out.println(name));
// Using method reference
names.forEach(System.out::println);
6. Optional
The Optional
class provides a more robust way to handle potentially null values without explicitly using null references.
Example:
String name = null;
// Before Java 8
if (name != null) {
System.out.println(name.length());
} else {
System.out.println("Name is null");
}
// Java 8 with Optional
Optional<String> optionalName = Optional.ofNullable(name);
optionalName.ifPresent(n -> System.out.println(n.length()));
These Java 8 features contribute to more expressive, concise, and maintainable code, enabling developers to write cleaner and more functional-style programs. Each feature addresses specific aspects of programming, promoting best practices and enhancing the overall development experience in Java.