This post is part of our Java Programming: A Comprehensive Guide for Beginners series.
19.1 Introduction
Java has evolved significantly over the years, introducing several advanced features and enhancements. Starting with Java 8, a major release, the language underwent transformation with the introduction of lambdas, the Stream API, and other features that enhance code expressiveness and functionality. Subsequent releases have continued to bring improvements, making Java a modern and powerful programming language. This chapter explores some of the advanced features introduced in Java 8 and beyond.19.2 Lambda Expressions
Lambda expressions, introduced in Java 8, are a concise way to express instances of single-method interfaces (functional interfaces). They facilitate the writing of more readable and functional code.The basic syntax of a lambda expression is as follows:
(parameters) -> expression
(parameters) -> { statements; }
(parameters) -> expression
(parameters) -> { statements; }
// Using lambda expression to create a Runnable
Runnable runnable = () -> System.out.println("Hello, Lambda!");
// Using lambda expression with parameters
MathOperation add = (a, b) -> a + b;
System.out.println("Result: " + add.operation(5, 3));
19.3 Functional Interfaces
Functional interfaces are interfaces with exactly one abstract method. They are essential for working with lambda expressions. Java provides a new annotation, @FunctionalInterface, to indicate that an interface is intended to be a functional interface.Code Example: Functional Interface
@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
19.4 Stream API
The Stream API, introduced in Java 8, provides a declarative approach for processing collections of data. It allows for functional-style operations on streams of elements, enabling concise and expressive code.19.4.1 Basics of Stream API
Streams are sequences of elements that support various operations like filter, map, reduce, and more.Code Example: Stream API Basics
List<String> programmingLanguages = Arrays.asList("Java", "Python", "JavaScript", "C++", "Ruby");
// Using stream to filter and print languages starting with 'J'
programmingLanguages.stream()
.filter(language -> language.startsWith("J"))
.forEach(System.out::println);
19.5 Default Methods
Default methods were introduced in Java 8 to allow the addition of new methods to interfaces without breaking the existing implementations. A default method has a default implementation provided in the interface itself.Code Example: Default Method
interface Greeting { void sayHello();
default void sayDefaultHello() { System.out.println("Default Hello!"); }}
class EnglishGreeting implements Greeting {
@Override public void sayHello() { System.out.println("Hello!"); }}
interface Greeting {
void sayHello();
default void sayDefaultHello() {
System.out.println("Default Hello!");
}
}
class EnglishGreeting implements Greeting {
@Override
public void sayHello() {
System.out.println("Hello!");
}
}
19.6 Method References
Method references provide a shorthand notation for lambda expressions to call methods by referring to their names directly. They make the code more readable.19.6.1 Types of Method References
- Static Method Reference: ClassName::staticMethodName
- Instance Method Reference: instance::instanceMethodName
- Constructor Reference: ClassName::new
Code Example: Method References
List<String> programmingLanguages = Arrays.asList("Java", "Python", "JavaScript", "C++", "Ruby");
// Using method reference to print each language
programmingLanguages.forEach(System.out::println);
19.7 Optional Class
The Optional class, introduced in Java 8, is a container object that may or may not contain a non-null value. It helps in avoiding NullPointerException and provides a more expressive way to handle optional values.Code Example: Optional Class
Optional<String> language = Optional.of("Java");
System.out.println("Language: " + language.orElse("Unknown"));
Optional<String> emptyLanguage = Optional.empty();
System.out.println("Empty Language: " + emptyLanguage.orElse("Unknown"));
19.8 New Date and Time API
Java 8 introduced a new Date and Time API in the java.time package, addressing the shortcomings of the old Date and Calendar classes.Code Example: New Date and Time API
// Creating and formatting dates
LocalDate currentDate = LocalDate.now();
System.out.println("Current Date: " + currentDate);
LocalTime currentTime = LocalTime.now();
System.out.println("Current Time: " + currentTime);
// Adding and subtracting durations
LocalDate futureDate = currentDate.plusDays(7);
System.out.println("Future Date: " + futureDate);
LocalTime futureTime = currentTime.plusHours(3);
System.out.println("Future Time: " + futureTime);
19.9 Java 9 Modules
Java 9 introduced the module system to address the issue of the monolithic structure of Java applications. Modules provide a way to encapsulate code and dependencies.19.9.1 Creating a Module
To create a module, a module-info.java file is added to the source code.module com.example.myapp {
exports com.example.mymodule ;
}
19.10 Java 10 Local Variable Type Inference
Java 10 introduced local variable type inference, allowing the use of the var keyword to declare local variables with inferred types.Code Example: Local Variable Type Inference
var number = 42;
var message = "Hello, Java 10!";
System.out.println(message + " The answer is: " + number);
19.11 Java 11 Features
Java 11 brought several enhancements, including the introduction of the var keyword for lambda parameters, the String method lines(), and the isBlank() method.Code Example: Java 11 Features
// Using var with lambda parameters
BiFunction<Integer, Integer, Integer> add = (var a, var b) -> a + b;
// Using String lines() method
String multilineText = "Line 1\nLine 2\nLine 3";
multilineText.lines()
.forEach(System.out::println);
// Using String isBlank() method
String emptyString = "";
System.out.println("Is String blank? " + emptyString.isBlank());
0 comments:
Post a Comment