Java 8 - New Features

Hello there, future Java wizards! I'm thrilled to embark on this exciting journey with you into the world of Java 8. As your friendly neighborhood computer science teacher, I've seen countless students transform from coding novices to programming prodigies. Today, we're going to explore some of the coolest features that Java 8 brought to the table. So, grab your favorite beverage, get comfy, and let's dive in!

Java 8 - New Features

Lambda Expressions

Imagine you're at a party, and someone asks you to quickly introduce yourself. You wouldn't start with your life story, right? You'd give a short, sweet introduction. That's exactly what lambda expressions are in Java - quick, to-the-point function definitions!

Let's look at a simple example:

// Before Java 8
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello, old Java!");
    }
};

// With Java 8 Lambda
Runnable runnableLambda = () -> System.out.println("Hello, Lambda!");

In this example, we're creating a Runnable object. The lambda expression () -> System.out.println("Hello, Lambda!"); is a shorthand way of defining the run() method. It's like saying, "When you run this, print 'Hello, Lambda!'".

Why Lambda Expressions are Cool

  1. They make your code more readable.
  2. They allow you to treat functionality as a method argument.
  3. They enable you to write more compact code.

Method References

Method references are like your smart friend who always knows the shortest route. They provide an even easier way to refer to methods or constructors.

Here's a tasty example:

List<String> fruits = Arrays.asList("apple", "banana", "cherry");

// Using lambda
fruits.forEach(fruit -> System.out.println(fruit));

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

In this fruity scenario, System.out::println is a method reference. It's saying, "For each fruit, use the println method of System.out".

Default Methods

Default methods are like that friend who always has a backup plan. They allow you to add new methods to interfaces without breaking existing implementations.

public interface Vehicle {
    default void startEngine() {
        System.out.println("Vroom! Engine started.");
    }
}

public class Car implements Vehicle {
    // No need to implement startEngine()
}

Car myCar = new Car();
myCar.startEngine(); // Outputs: Vroom! Engine started.

Here, startEngine() is a default method in the Vehicle interface. Any class implementing Vehicle gets this method for free!

Stream API

The Stream API is like having a super-efficient assembly line for your data. It allows you to process collections of objects in a declarative way.

Let's see it in action:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// Sum of even numbers
int sum = numbers.stream()
                 .filter(n -> n % 2 == 0)
                 .mapToInt(Integer::intValue)
                 .sum();

System.out.println("Sum of even numbers: " + sum);

This code is like saying, "Take this list of numbers, keep only the even ones, convert them to int, and sum them up." It's that simple!

Optional Class

The Optional class is like a safety net for your null values. It helps prevent those pesky NullPointerExceptions.

String name = null;
Optional<String> optionalName = Optional.ofNullable(name);

// Instead of: if (name != null) { ... }
optionalName.ifPresent(n -> System.out.println("Hello, " + n));

// Or provide a default value
String greeting = optionalName.orElse("stranger");
System.out.println("Hello, " + greeting);

With Optional, you're always prepared, whether you have a value or not!

New Date Time API

Java 8 introduced a new date and time API that's much more intuitive and easier to use than the old java.util.Date.

LocalDate today = LocalDate.now();
System.out.println("Today's date: " + today);

LocalTime currentTime = LocalTime.now();
System.out.println("Current time: " + currentTime);

LocalDateTime currentDateTime = LocalDateTime.now();
System.out.println("Current date and time: " + currentDateTime);

// Adding 1 week to the current date
LocalDate nextWeek = today.plusWeeks(1);
System.out.println("Date after 1 week: " + nextWeek);

This new API makes working with dates and times as easy as checking your watch!

Nashorn JavaScript Engine

Last but not least, Java 8 introduced the Nashorn JavaScript engine, allowing you to run JavaScript code within your Java applications. It's like having a bilingual friend who can translate between Java and JavaScript!

import javax.script.*;

public class NashornExample {
    public static void main(String[] args) throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("nashorn");

        engine.eval("print('Hello from JavaScript!');");
    }
}

This code snippet runs JavaScript right inside your Java program. How cool is that?

To wrap up, Java 8 brought a ton of exciting features that make coding easier, more efficient, and more fun. As we've seen, these features aren't just bells and whistles - they're powerful tools that can significantly improve your code.

Remember, learning to code is a journey. Don't worry if everything doesn't click right away. Keep practicing, keep exploring, and most importantly, keep having fun! Before you know it, you'll be writing Java like a pro. Happy coding, future Java ninjas!

Credits: Image by storyset