minte9
LearnRemember



Anonymous

Anonymous inner classes make it easier to pass around code as data.
 
/**
 * Anonymous inner classes make it easier to pass around code as data.
 * 
 * Example: 
 * Using an anonymous inner class to associate behavior with a button click.
 * 
 * There are four lines of boilerplate code in order to call ...
 * one line of important logic.
 */

package com.minte9.lambdas.expressions;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Anonimous {
    public static void main(String[] args) {

        JFrame frame = new JFrame();
        JButton button = new JButton("Click me");

        button.addActionListener(
            new ActionListener() { // Look Here
                @Override 
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Button clicked");
                }
            }
        );
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
        frame.getContentPane().add(button); 
        frame.setSize(300, 300);
        frame.setVisible(true);
    }
}

Behavior

Starting with Java 8 we can use lambdas expressions, to pass behavior not objects.
 
/**
 * Instead of passing an object we are passing a block of code.
 * 
 * We pass a function without a name. 
 * Javac is inferring the type of event from its context.
 */

package com.minte9.lambdas.expressions;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Behavior {
    public static void main(String[] args) {

        JFrame frame = new JFrame();
        JButton button = new JButton("Click me");

        button.addActionListener(
            event -> System.out.println("Button clicked") // Look Here
        );
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
        frame.getContentPane().add(button); 
        frame.setSize(300, 300);
        frame.setVisible(true);
    }
}

Lambdas

There are different ways of writing lambda expressions.
 
/**
 * There are different ways of writing lambda expressions.
 * 
 * Lambda expression with no arguments.
 * Lambda expression in a full block.
 * Lambda expression with more arguments.
 * 
 * Method parameters require less boilerplate but still ...
 * they are still statically typed!
 *  
 */

package com.minte9.lambdas.expressions;
import java.util.function.BinaryOperator;

public class Lambdas {
    public static void main(String[] args) {

        Runnable noArgs = () -> System.out.println("Hello World");
        new Thread(noArgs).run(); 
            // Hello World

        Runnable multiStatement = () -> {
            System.out.println("Hello");
            System.out.println("World");
        };
        new Thread(multiStatement).run(); 
            // Hello 
            // World

        BinaryOperator<Integer> op = (x, y) -> x + y;
        System.out.println(op.apply(2, 3)); 
            // 5
    }
}

Final Variable

To use a variable from outside an anonymous inner class it must be final.
 
/**
 * To use a variable from outside an anonymous inner class the variable ...
 * must be final (or effective final).
 * 
 * The Holder variable is effective final,
 * even if the final keyword it is not required (Java 8)
 */

package com.minte9.lambdas.expressions;
import java.util.Arrays;
import javax.xml.ws.Holder;

public class FinalVariable {
    public static void main(String[] args) {

        Holder<Integer> holder = new Holder<>(0);
        Arrays.asList("a", "b", "c").forEach((x) -> {
            holder.value ++;
        });
        System.out.println(holder.value); 
            // 3
        
        final String str = "A";
        Arrays.asList("a", "b", "c").forEach((x) -> {
            // str = str + x; 
            // Error: final local variable cannot be assigned
        }); 
        System.out.println(str);
            // A
    }
}

Type inference

Javac type inference is smart, but it needs enought information.
 
/**
 * Javac type inference is smart, but it needs enought information. 
 */

package com.minte9.lambdas.expressions;
import java.util.function.Function;

public class TypeInference {
    public static void main(String[] args) {

        // Wrong - doesn't compile
        /*
            Function op = x -> x + 1;
        */

        // Correct
        Function<Long, Long> op = x -> x + 1;
        System.out.println(op.apply(20L)); // 21
    }
}



  Last update: 203 days ago