Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

Java 8 Features Lambda, Streams, Optional: Tutorial, Examples, FAQs & Interview Tips

Lambda Expressions

A lambda expression is a concise way to represent an anonymous function (a block of code that can be passed around). Syntax: (parameters) -> expression or (parameters) -> { statements; }

Lambda & Functional Interfaces
import java.util.*;
import java.util.function.*;

// Custom functional interface (exactly one abstract method)
@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);
}

public class LambdaDemo {
    public static void main(String[] args) {
        // Lambda implementing a functional interface
        MathOperation add      = (a, b) -> a + b;
        MathOperation multiply = (a, b) -> a * b;
        System.out.println(add.operate(5, 3));       // 8
        System.out.println(multiply.operate(5, 3));  // 15

        // Built-in functional interfaces (java.util.function)
        Predicate<Integer> isEven = n -> n % 2 == 0;
        Function<String, Integer> strLen = s -> s.length();
        Consumer<String> printer = s -> System.out.println(">> " + s);
        Supplier<String> greeting = () -> "Hello, Java 8!";

        System.out.println(isEven.test(4));       // true
        System.out.println(strLen.apply("Java")); // 4
        printer.accept("Lambda!");                // >> Lambda!
        System.out.println(greeting.get());       // Hello, Java 8!

        // Lambda with collections
        List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
        names.sort((a, b) -> a.compareTo(b));
        names.forEach(name -> System.out.print(name + " "));  // Alice Bob Charlie
        System.out.println();
    }
}

Stream API

The Stream API lets you process collections in a declarative, pipeline style. Streams are lazy - intermediate operations are only executed when a terminal operation is called.

Stream API & Method References
import java.util.*;
import java.util.stream.*;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // filter + map + collect
        List<Integer> evenSquares = numbers.stream()
            .filter(n -> n % 2 == 0)          // keep evens: 2,4,6,8,10
            .map(n -> n * n)                   // square them: 4,16,36,64,100
            .collect(Collectors.toList());
        System.out.println(evenSquares);  // [4, 16, 36, 64, 100]

        // reduce - sum all elements
        int sum = numbers.stream()
            .reduce(0, Integer::sum);
        System.out.println("Sum: " + sum);  // 55

        // count, min, max
        long count = numbers.stream().filter(n -> n > 5).count();
        System.out.println("Count > 5: " + count);  // 5

        Optional<Integer> max = numbers.stream().max(Integer::compareTo);
        max.ifPresent(m -> System.out.println("Max: " + m));  // Max: 10

        // Method references - shorthand for lambdas
        List<String> words = Arrays.asList("hello", "world", "java", "streams");
        words.stream()
             .map(String::toUpperCase)          // instance method reference
             .sorted()
             .forEach(System.out::println);     // static method reference

        // Collectors.joining
        String joined = words.stream().collect(Collectors.joining(", ", "[", "]"));
        System.out.println(joined);  // [hello, world, java, streams]
    }
}

Optional Class

Optional - Avoiding NullPointerException
import java.util.Optional;

public class OptionalDemo {

    static Optional<String> findUser(int id) {
        if (id == 1) return Optional.of("Alice");
        return Optional.empty();
    }

    public static void main(String[] args) {
        Optional<String> user1 = findUser(1);
        Optional<String> user2 = findUser(99);

        // isPresent / get
        if (user1.isPresent()) {
            System.out.println("Found: " + user1.get());  // Found: Alice
        }

        // orElse - default value if empty
        System.out.println(user2.orElse("Guest"));  // Guest

        // orElseGet - lazy default
        System.out.println(user2.orElseGet(() -> "Anonymous"));  // Anonymous

        // map - transform if present
        user1.map(String::toUpperCase)
             .ifPresent(System.out::println);  // ALICE

        // orElseThrow
        try {
            user2.orElseThrow(() -> new RuntimeException("User not found"));
        } catch (RuntimeException e) {
            System.out.println(e.getMessage());  // User not found
        }
    }
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.