DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • The Complete Guide to Stream API and Collectors in Java 8
  • Java Stream API: 3 Things Every Developer Should Know About
  • Mastering Concurrency: An In-Depth Guide to Java's ExecutorService
  • Understanding Lazy Evaluation in Java Streams

Trending

  • Beyond Microservices: The Emerging Post-Monolith Architecture for 2025
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • AI-Assisted Coding for iOS Development: How Tools like CursorAI Are Redefining the Developer Workflow
  • Securing Parquet Files: Vulnerabilities, Mitigations, and Validation
  1. DZone
  2. Data Engineering
  3. Data
  4. A Little Lazy Lambda Tutorial

A Little Lazy Lambda Tutorial

Let's see how you can enhance performance while also keeping your code tidy through the glorious use of lambda expressions.

By 
Dan Newton user avatar
Dan Newton
·
May. 01, 17 · Tutorial
Likes (42)
Comment
Save
Tweet
Share
38.8K Views

Join the DZone community and get the full member experience.

Join For Free

Everyone is a bit lazy, so why not our code? Lambda expressions in Java 8 allow us to make our code that bit lazier, In this short post, I will cover how using Lambda expressions can make code more lazy.

If you have not used Lambda expressions before have a look at my some of my previous posts A Little Lambda Tutorial and Java 8 Streams for some background information not in this post.

So, first things first, what does being lazy mean? We’ll I’m sure you know the answer, as you have probably left things to the last minute and then quickly rushed to complete it at the end or even not do it at all. That is basically the definition of lazy evaluation, which defers the evaluation of a method until another expression requires it. If an expression never calls the lazy method, then it will just lie around and do nothing. Java, on the other hand, uses eager evaluation by default and will execute a method as soon as it is called.

Lambdas allows Java to be lazy, as they represent a function to be executed that can be passed around and will only be evaluated when required. The examples below are pretty simple but should demonstrate the order of execution, showing that the lambdas are not executed straight away.

If we start with a basic piece of code that is not using lambdas, we can see how they execute sequentially.

public class NonLazyCodeExample {
    public static void main(String args[]) {
        final int number = 4;
        final boolean computeResult = compute(number);
        final boolean processResult = process(number);
        if (computeResult && processResult) {
            System.out.println("TRUE");
        } else {
            System.out.println("FALSE");
        }
    }
    public static boolean compute(final int number) {
        System.out.println("computing number : " + number);
        return number > 5 ? true : false;
    }
    public static boolean process(final int number) {
        System.out.println("processing number : " + number);
        return number % 3 == 0 ? true : false;
    }
}


Which outputs:

computing number : 4
processing number : 4
FALSE


This is due to both compute and process being called straight away when they are assigned to their variables. The execution of process was wasted, as the second condition of the if statement was never reached. Obviously, this example is extremely simple and most people will mention that the code can be rewritten to:

public class NonLazyCodeExample {
    public static void main(String args[]) {
        final int number = 4;
        if (compute(number) && process(number)) {
            System.out.println("TRUE");
        } else {
            System.out.println("FALSE");
        }
    }
    public static boolean compute(final int number) {
        System.out.println("computing number : " + number);
        return number > 5 ? true : false;
    }
    public static boolean process(final int number) {
        System.out.println("processing number : " + number);
        return number % 3 == 0 ? true : false;
    }
}


Which will now output:

computing number : 4
FALSE


The process method is never called due to the if statement evaluating to false as soon as compute is executed. So why not do this in the first place? A possible reason against this is if longer methods are put into the if statement, maybe with a few parameters, it will start to get messy and you might struggle to read it. Whereas executing the methods earlier and assigning them to variables should make the if statement itself shorter and easier to understand.

Using lambdas will combine both readability and removal of unneeded computations by allowing us to define them to a variable without executing them. The example below should make this clearer.

public class LazyCodeExample {
    public static void main(String args[]) {
        final int number = 4;
        final Supplier < Boolean > computeResult = () - > compute(number);
        final Supplier < Boolean > processResult = () - > process(number);
        if (computeResult.get() && processResult.get()) {
            System.out.println("TRUE");
        } else {
            System.out.println("FALSE");
        }
    }
    public static boolean compute(final int number) {
        System.out.println("computing number : " + number);
        return number > 5 ? true : false;
    }
    public static boolean process(final int number) {
        System.out.println("processing number : " + number);
        return number % 3 == 0 ? true : false;
    }
}


Just for clarification, the output is:

computing number : 4
FALSE


As you can see, this is the same output as the previous example, showing that the same methods were executed in both. The compute and process methods are added to lambda expressions, which are stored in variables using the Supplier Functional Interface. The Supplier has a single method, get, which executes the lambda that it represents.

Therefore, when...

computeResult.get()


...is called, the function it represents is executed, which, in turn, calls and executes the compute method. As this returned false, the if statement also evaluated to false and processResult.get is never called, leaving the process method to never be executed.

Another example can be shown with the use of a Stream, which also will not be executed straight away.

public class LazyStreamExample {
    public static void main(String args[]) {
        final List < Integer > numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        System.out.println("DEFINING THE STREAM");
        final Stream < Integer > stream = numbers.stream().filter(LazyStreamExample::compute).filter(LazyStreamExample::process);
        System.out.println("NOT EXECUTED YET");
        final int result = stream.findFirst().orElse(0);
        System.out.println("THE RESULT IS : " + result);
    }
    public static boolean compute(final int number) {
        System.out.println("computing number : " + number);
        return number > 5 ? true : false;
    }
    public static boolean process(final int number) {
        System.out.println("processing number : " + number);
        return number % 3 == 0 ? true : false;
    }
}


Producing the follow output:

DEFINING THE STREAM
NOT EXECUTED YET
computing number : 1
computing number : 2
computing number : 3
computing number : 4
computing number : 5
computing number : 6
processing number : 6
THE RESULT IS : 6


A Stream is created from the numbers list and stored within a variable. Like before, with the Supplier, it will not be executed until a dependent method is run. In this example, the findFirst method is used, but unlike the Supplier, the Stream has many more methods that can execute it, such as: collect, findAny, and count.

Well done if you have made it to the end of this post (even thought it is short) and you have proved you are not lazy yourself. Or you scrolled to the end without actually reading it, in which case you are lazy. Anyway, through the use of some lazy lambdas we can keep our code easy to read without sacrificing performance by executing unneeded operations.

Java (programming language) POST (HTTP) Stream (computing) Evaluation Execution (computing) Data Types Interface (computing)

Published at DZone with permission of Dan Newton, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • The Complete Guide to Stream API and Collectors in Java 8
  • Java Stream API: 3 Things Every Developer Should Know About
  • Mastering Concurrency: An In-Depth Guide to Java's ExecutorService
  • Understanding Lazy Evaluation in Java Streams

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!