Java 8 Features Overview

Loading

Java 8, released in March 2014, introduced several groundbreaking features that revolutionized Java programming. These features enhanced productivity, readability, and performance. Below is an overview of the key features introduced in Java 8:


1. Lambda Expressions

Lambda expressions enable functional programming in Java by allowing you to write concise and readable code for anonymous methods.

Syntax

(parameters) -> expression

Example

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// Without lambda
names.forEach(new Consumer<String>() {
    @Override
    public void accept(String name) {
        System.out.println(name);
    }
});

// With lambda
names.forEach(name -> System.out.println(name));

2. Functional Interfaces

A functional interface is an interface with exactly one abstract method. Lambda expressions can be used to implement functional interfaces.

Example

@FunctionalInterface
interface Greeting {
    void greet(String name);
}

public class FunctionalInterfaceExample {
    public static void main(String[] args) {
        Greeting greeting = name -> System.out.println("Hello, " + name);
        greeting.greet("Alice");
    }
}

3. Stream API

The Stream API provides a powerful way to process collections of objects in a functional style. It supports operations like filtering, mapping, and reducing.

Example

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

// Filter names starting with 'A' and convert to uppercase
List<String> result = names.stream()
                           .filter(name -> name.startsWith("A"))
                           .map(String::toUpperCase)
                           .collect(Collectors.toList());

System.out.println(result); // Output: [ALICE]

4. Default Methods in Interfaces

Default methods allow interfaces to have method implementations. This feature enables backward compatibility when adding new methods to existing interfaces.

Example

interface Vehicle {
    void start();

    default void stop() {
        System.out.println("Vehicle stopped.");
    }
}

class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car started.");
    }
}

public class DefaultMethodExample {
    public static void main(String[] args) {
        Car car = new Car();
        car.start(); // Output: Car started.
        car.stop();  // Output: Vehicle stopped.
    }
}

5. Static Methods in Interfaces

Interfaces can now have static methods, which are useful for utility methods.

Example

interface MathOperations {
    static int add(int a, int b) {
        return a + b;
    }
}

public class StaticMethodExample {
    public static void main(String[] args) {
        int result = MathOperations.add(5, 10);
        System.out.println("Sum: " + result); // Output: Sum: 15
    }
}

6. Method References

Method references provide a shorthand notation for lambda expressions that call existing methods.

Types of Method References

  1. Static Method Reference: ClassName::staticMethod
  2. Instance Method Reference: instance::instanceMethod
  3. Constructor Reference: ClassName::new

Example

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// Using lambda
names.forEach(name -> System.out.println(name));

// Using method reference
names.forEach(System.out::println);

7. Optional Class

The Optional class is a container object that may or may not contain a non-null value. It helps avoid NullPointerException.

Example

Optional<String> name = Optional.ofNullable(getName());

if (name.isPresent()) {
    System.out.println("Name: " + name.get());
} else {
    System.out.println("Name not found.");
}

8. New Date and Time API

Java 8 introduced the java.time package, which provides a modern and comprehensive API for date and time manipulation.

Example

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;

public class DateTimeExample {
    public static void main(String[] args) {
        LocalDate date = LocalDate.now();
        LocalTime time = LocalTime.now();
        LocalDateTime dateTime = LocalDateTime.now();

        System.out.println("Date: " + date);
        System.out.println("Time: " + time);
        System.out.println("DateTime: " + dateTime);
    }
}

9. Nashorn JavaScript Engine

Java 8 introduced the Nashorn JavaScript engine, which allows you to execute JavaScript code within Java applications.

Example

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class NashornExample {
    public static void main(String[] args) throws ScriptException {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        engine.eval("print('Hello, Nashorn!');");
    }
}

10. Parallel Array Sorting

Java 8 introduced parallel sorting for arrays using the Arrays.parallelSort() method.

Example

import java.util.Arrays;

public class ParallelSortExample {
    public static void main(String[] args) {
        int[] numbers = {5, 3, 9, 1, 7};

        Arrays.parallelSort(numbers);

        System.out.println("Sorted Array: " + Arrays.toString(numbers));
    }
}

11. Base64 Encoding and Decoding

Java 8 added built-in support for Base64 encoding and decoding.

Example

import java.util.Base64;

public class Base64Example {
    public static void main(String[] args) {
        String original = "Hello, Java 8!";
        String encoded = Base64.getEncoder().encodeToString(original.getBytes());
        String decoded = new String(Base64.getDecoder().decode(encoded));

        System.out.println("Encoded: " + encoded);
        System.out.println("Decoded: " + decoded);
    }
}

12. CompletableFuture

The CompletableFuture class provides a way to write asynchronous, non-blocking code.

Example

import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
    public static void main(String[] args) {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, CompletableFuture!");

        future.thenAccept(System.out::println);
    }
}

13. Type Annotations

Java 8 extended the use of annotations to any type, not just declarations.

Example

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@interface NonNull {}

public class TypeAnnotationExample {
    public static void main(@NonNull String[] args) {
        @NonNull String message = "Hello, Type Annotations!";
        System.out.println(message);
    }
}

14. StringJoiner

The StringJoiner class simplifies the process of joining strings with a delimiter.

Example

import java.util.StringJoiner;

public class StringJoinerExample {
    public static void main(String[] args) {
        StringJoiner joiner = new StringJoiner(", ", "[", "]");
        joiner.add("Alice").add("Bob").add("Charlie");

        System.out.println(joiner.toString()); // Output: [Alice, Bob, Charlie]
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *