001package java8;
002
003import com.sandwich.koan.Koan;
004
005import java.util.function.Function;
006
007import static com.sandwich.koan.constant.KoanConstants.__;
008import static com.sandwich.util.Assert.assertEquals;
009
010public class AboutLambdas {
011
012    interface Caps {
013        public String capitalize(String name);
014    }
015
016    String fieldFoo = "Lambdas";
017
018    @Override
019    public String toString() {
020        return "CAPS";
021    }
022
023    static String str = "";
024
025    //lambda has access to "this"
026    Caps lambdaField = s -> this.toString();
027    //lambda has access to object methods
028    Caps lambdaField2 = s -> toString();
029
030    @Koan
031    public void verySimpleLambda() throws InterruptedException {
032        Runnable r8 = () -> str = "changed in lambda";
033        r8.run();
034        assertEquals(str, __);
035    }
036
037    @Koan
038    public void simpleLambda() {
039        Caps caps = (String n) -> {
040            return n.toUpperCase();
041        };
042        String capitalized = caps.capitalize("James");
043        assertEquals(capitalized, __);
044    }
045
046    @Koan
047    public void simpleSuccinctLambda() {
048        //parameter type can be omitted,
049        //code block braces {} and return statement can be omitted for single statement lambda
050        //parameter parenthesis can be omitted for single parameter lambda
051        Caps caps = s -> s.toUpperCase();
052        String capitalized = caps.capitalize("Arthur");
053        assertEquals(capitalized, __);
054    }
055
056    @Koan
057    public void lambdaField() {
058        assertEquals(lambdaField.capitalize(""), __);
059    }
060
061    @Koan
062    public void lambdaField2() {
063        assertEquals(lambdaField2.capitalize(""), __);
064    }
065
066    @Koan
067    public void effectivelyFinal() {
068        //final can be omitted like this:
069        /* final */
070        String effectivelyFinal = "I'm effectively final";
071        Caps caps = s -> effectivelyFinal.toUpperCase();
072        assertEquals(caps.capitalize(effectivelyFinal), __);
073    }
074
075    @Koan
076    public void methodReference() {
077        Caps caps = String::toUpperCase;
078        String capitalized = caps.capitalize("Gosling");
079        assertEquals(capitalized, __);
080    }
081
082    @Koan
083    public void thisIsSurroundingClass() {
084        //"this" in lambda points to surrounding class
085        Function<String, String> foo = s -> s + this.fieldFoo + s;
086        assertEquals(foo.apply("|"), __);
087    }
088
089}
090