Java Evolution: Inner Classes to Lambda Expressions and Stream API

Inner Classes

Member Inner Classes


public class OuterClass {
    public static void main(String[] args) {
        // Accessing member inner class from member method
        OuterClass outer = new OuterClass();
        outer.processData();

        // Direct access to member inner class
        OuterClass.InnerClass inner = new OuterClass().new InnerClass();
        inner.displayInfo();
    }

    private String identifier = "Global Identifier";

    public void processData() {
        InnerClass innerRef = new InnerClass();
        System.out.println(innerRef.localIdentifier);
    }

    public class InnerClass {
        private String localIdentifier = "Local Identifier";

        public void displayInfo() {
            String tempVar = "Temporary Value";
            // Accessing local variable
            System.out.println(tempVar);
            // Accessing inner class member
            System.out.println(this.localIdentifier);
            // Accessing outer class member
            System.out.println(OuterClass.this.identifier);
        }
    }
}

Local Inner Classes


public class ContainerClass {
    public static void main(String[] args) {
        ContainerClass container = new ContainerClass();
        container.executeOperation();
    }

    public void executeOperation() {
        int counter = 0;
        class LocalInnerClass {
            public void performTask() {
                System.out.println(counter); // Local variable must be effectively final
            }
        }
        new LocalInnerClass().performTask();
    }
}

Lambda Expressions


public class LambdaDemo {
    public static void main(String[] args) {
        Integer[] values = {10, 20, 5, 15, 25, 8, 12, 18};
        List<integer> numberList = new ArrayList<>();
        Collections.addAll(numberList, values);
        
        // Lambda expression requirements: interface must have exactly one abstract method
        // Parentheses can be omitted when there's only one parameter
        // Braces, return, and semicolon can be omitted for single-line expressions
        // Parameter types can be omitted when type can be inferred from context
        
        Collections.sort(numberList, (x, y) -> y.compareTo(x));
        System.out.println("Sorted in descending order: " + numberList);
    }
}
</integer>

Fnuctional Intefraces


@FunctionalInterface // Ensures the interface has exactly one abstract method
public interface CustomFunction {
    void execute();
}


public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        FunctionalInterfaceDemo demo = new FunctionalInterfaceDemo();

        // Functional interfaces often used as method parameters or return values
        // Functional interface reference == lambda expression
        // Functional interface reference.method(params) == lambda expression body

        // Double colon (::) syntax:
        // param->(object, class, super, this).method(param) == (object, class, super, this)::method
        // param->new Class(param) == Class::new

//        System.out.println(demo.getStringSupplier(() -> "Hello"));

//        demo.processString("Test", 
//            input -> System.out.println("Processing: " + input), 
//            input -> System.out.println("Final result: " + input));

//        System.out.println(demo.validateString("Test", 
//            input -> input.length() > 3, 
//            input -> input.startsWith("T")));

        System.out.println(demo.transformString("Java Programming", 
            input -> input.replace(" ", "_")));
    }

    public String getStringSupplier(Supplier<string> supplier) {
        return supplier.get();
    }

    public void processString(String text, Consumer<string> processor1, Consumer<string> processor2) {
        processor1.andThen(processor2).accept(text);
    }

    public boolean validateString(String text, Predicate<string> validator1, Predicate<string> validator2) {
        return validator1.or(validator2).test(text);
    }

    public String transformString(String input, Function<string string=""> transformer) {
        return transformer.apply(input);
    }
}
</string></string></string></string></string></string>

Stream API


public class StreamProcessing {
    public static void main(String[] args) {
        // Intermediate operations (return Stream): filter, map, limit, skip
        // Terminal operations: forEach, count

        List<string> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        names.add("David");
        names.add("Eve");
        names.add("Frank");

        names.stream()
                .map(name -> name + " Smith") // Transform elements
                .limit(4) // Limit to first 4 elements
                .skip(1) // Skip first element
                .filter(name -> name.startsWith("B")) // Filter elements
                .forEach(name -> System.out.println(name)); // Process elements

        System.out.println("Total elements: " + names.stream().count());

        List<integer> numbers = new ArrayList<>();
        numbers.add(100);
        numbers.add(200);
        numbers.add(300);

        Stream extends Serializable> combinedStream = Stream.concat(names.stream(), numbers.stream());
        combinedStream.forEach(item -> System.out.println("Combined: " + item));
    }
}
</integer></string>

Tags: java-inner-classes java-lambda-expressions java-functional-interfaces java-stream-api

Posted on Tue, 13 Oct 2026 16:37:53 +0000 by spires