VisualStudioTutor.com Java Tutorial All Lessons

Lesson 21 of 25

Lambda Expressions and Date/Time

Write concise behavior with lambda expressions and work safely with modern Java date and time classes.

Learning objectives

  • Explain what a lambda expression represents.
  • Use lambdas with functional interfaces such as Predicate, Consumer, and Comparator.
  • Sort and filter collections with lambdas.
  • Create dates and times using LocalDate, LocalTime, and LocalDateTime.
  • Format dates and calculate date differences with DateTimeFormatter and Period.

1. What is a lambda expression?

A lambda expression is a compact way to provide the implementation of a functional interface—an interface with one abstract method. Instead of creating a separate class just to supply a small piece of behavior, you can write the behavior inline.

Example: from anonymous behavior to lambda

interface Greeting {
    void sayHello(String name);
}

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

        greeting.sayHello("Amina");
    }
}

The parameter name is passed to the lambda, and the code after -> is executed when sayHello is called.

2. Lambdas with built-in functional interfaces

Java provides common functional interfaces in java.util.function. Three useful examples are Predicate<T> for true/false tests, Consumer<T> for actions, and Function<T,R> for transformations.

Example: Predicate and Consumer

import java.util.function.Consumer;
import java.util.function.Predicate;

public class FunctionalDemo {
    public static void main(String[] args) {
        Predicate<Integer> isPass = mark -> mark >= 50;
        Consumer<String> printMessage = message ->
            System.out.println(message);

        int mark = 72;

        printMessage.accept(
            isPass.test(mark) ? "Pass" : "Fail"
        );
    }
}

3. Sorting with a lambda

Lambdas are especially useful when a method needs a small rule, such as a comparison strategy.

import java.util.ArrayList;
import java.util.List;

public class SortNames {
    public static void main(String[] args) {
        List<String> names =
            new ArrayList<>(List.of("Mei", "Amina", "Daniel"));

        names.sort((a, b) -> a.compareToIgnoreCase(b));

        names.forEach(name -> System.out.println(name));
    }
}

The first lambda tells sort how two names should be compared. The second lambda tells forEach what to do with each item.

4. Modern Java date and time classes

The java.time package provides immutable, type-safe date and time classes. Use LocalDate when you need a date without a time zone, LocalTime for a time of day, and LocalDateTime when both are required.

Example: create and manipulate dates

import java.time.LocalDate;

public class DateDemo {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDate examDate = today.plusDays(30);

        System.out.println("Today: " + today);
        System.out.println("Exam : " + examDate);
    }
}

5. Formatting dates

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateFormatting {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2026, 8, 8);

        DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("dd MMMM yyyy");

        System.out.println(date.format(formatter));
    }
}

6. Calculating age with Period

import java.time.LocalDate;
import java.time.Period;

public class AgeCalculator {
    public static void main(String[] args) {
        LocalDate birthDate = LocalDate.of(2000, 5, 20);
        LocalDate today = LocalDate.now();

        Period age = Period.between(birthDate, today);

        System.out.println("Age: " + age.getYears() + " years");
    }
}

Mini project: upcoming-event sorter

This mini project combines lambdas and date/time. Events are sorted by date and only future events are displayed.

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

record Event(String title, LocalDate date) {}

public class EventPlanner {
    public static void main(String[] args) {
        List<Event> events = new ArrayList<>();

        events.add(new Event(
            "Java Assessment",
            LocalDate.now().plusDays(14)
        ));

        events.add(new Event(
            "Project Presentation",
            LocalDate.now().plusDays(7)
        ));

        events.add(new Event(
            "Old Workshop",
            LocalDate.now().minusDays(2)
        ));

        events.removeIf(
            event -> event.date().isBefore(LocalDate.now())
        );

        events.sort(
            (a, b) -> a.date().compareTo(b.date())
        );

        DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("dd MMM yyyy");

        events.forEach(event ->
            System.out.println(
                event.date().format(formatter)
                + " - " + event.title()
            )
        );
    }
}

Common mistakes

ProblemWhy it happensFix
Using a lambda where several complex statements are neededThe lambda becomes difficult to read.Move complex logic into a named method and reference it.
Using java.util.Date for new code unnecessarilyThe older API is mutable and less expressive.Prefer java.time classes for modern applications.
Comparing dates as formatted stringsText ordering may not represent chronological order.Compare LocalDate values directly.

Summary

You learned how lambdas provide compact implementations of functional interfaces and how the java.time API models dates and times. In Lesson 22, you will apply event-driven programming concepts to desktop interfaces using Java Swing.