1. Lambda Expressions
Lambda expressions are a way to define anonymous functions (functions without a name) that can be passed as arguments to other methods. They are used primarily to implement simple instances of functional interfaces.
Syntax:
(parameters) -> expression
Example:
List<String> names = Arrays.asList("John", "Jane", "Jack", "Doe");
names.forEach(name -> System.out.println(name));
Explanation:
In the example above, name -> System.out.println(name)
is a lambda expression that prints each name in the list.
2. Functional Interfaces
A functional interface is an interface with a single abstract method, and it can have multiple default or static methods. Lambda expressions are used to instantiate these interfaces.
Example:
@FunctionalInterface
interface Greeting {
void sayHello();
}
Explanation:
Here, Greeting
is a functional interface with a single abstract method sayHello
.
3. Stream API
The Stream API is used to process sequences of elements (such as collections) in a functional-style. It provides methods to perform operations like filter, map, and reduce.
Example:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers);
Explanation:
In the example, stream()
creates a stream from the list of numbers, filter(n -> n % 2 == 0)
filters out the even numbers, and collect(Collectors.toList())
collects the filtered results into a list.
4. Default Methods
Default methods are methods in an interface with a default implementation. They allow adding new methods to interfaces without breaking the implementing classes.
Example:
interface Vehicle {
default void print() {
System.out.println("I am a vehicle");
}
}
class Car implements Vehicle {}
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.print();
}
}
Explanation:
In the example, the Vehicle
interface has a default method print
. The Car
class implements Vehicle
and inherits the default method.
5. Optional Class
The Optional
class is a container object which may or may not contain a non-null value. It is used to avoid NullPointerException
and to handle null values gracefully.
Example:
Optional<String> optional = Optional.ofNullable("Hello");
optional.ifPresent(System.out::println);
Explanation:
In the example, Optional.ofNullable("Hello")
creates an optional containing the string "Hello". The ifPresent
method prints the value if it is present.
6. New Date and Time API
Java 8 introduced a new date and time API under the java.time
package. It is more comprehensive and easier to use than the old java.util.Date
and java.util.Calendar
classes.
Example:
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1990, Month.FEBRUARY, 5);
Period age = Period.between(birthday, today);
System.out.println("Age: " + age.getYears());
Explanation:
In the example, LocalDate.now()
gets the current date, and LocalDate.of(1990, Month.FEBRUARY, 5)
creates a date for a specific birthday. Period.between(birthday, today)
calculates the period between the two dates, which can be used to determine the age.
7. Nashorn JavaScript Engine
Nashorn is a JavaScript engine that allows you to run JavaScript code on the Java Virtual Machine (JVM).
Example:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
try {
engine.eval("print('Hello, Nashorn');");
} catch (ScriptException e) {
e.printStackTrace();
}
Explanation:
In the example, ScriptEngineManager
and ScriptEngine
are used to evaluate and execute a JavaScript code snippet from within Java.
8. Method References
Method references provide a way to refer to methods without invoking them. They are a shorthand notation of a lambda expression to call a method.
Example:
List<String> names = Arrays.asList("John", "Jane", "Jack", "Doe");
names.forEach(System.out::println);
Explanation:
In the example, System.out::println
is a method reference that refers to the println
method of System.out
.
9. Base64 Encoding and Decoding
Java 8 provides a Base64 class for encoding and decoding text using Base64 encoding scheme.
Example:
String originalInput = "test input";
String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());
System.out.println(encodedString);
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);
System.out.println(decodedString);
Explanation:
In the example, Base64.getEncoder().encodeToString
encodes a string into Base64 format, and Base64.getDecoder().decode
decodes it back to the original string.