Runnable Lambda
package com.xxb.java.lambda;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
class Java8Lambda {
  public static void main(String[] args) {
        runnableTest();
        comparatorTest();
        loopingTest();
        chainingAndFilter();
        mutationAndResults();
        calculatingWithMap();
    }
    public static void loopingTest(){
        List<Person> pl = Person.createShortList();
        pl.forEach(Person::printName);
    }
    public static void chainingAndFilter(){
        List<Person> pl = Person.createShortList();
        System.out.println("\n=== Western Pilot Phone List ===");
        System.out.println("\n=== Eastern Draftee Phone List ===");
        pl.stream().filter(person -> person.getAge() > 10).forEach(Person::print);
    }
    private static void mutationAndResults(){
        List<Person> list = Person.createShortList();
        List<Person> persons = list.stream().filter(person -> person.getAge() > 10).collect(Collectors.toList());
        persons.forEach(Person::print);
    }
    private static void calculatingWithMap(){
        List<Person> personList =Person.createShortList();
        // Calc average age of pilots old style
        System.out.println("== Calc Old Style ==");
        int sum = 0;
        int count = 0;
        for (Person p:personList){
            if (p.getAge() >= 23 && p.getAge() <= 65 ){
                sum = sum + p.getAge();
                count++;
            }
        }
        long average = sum / count;
        System.out.println("Total Ages: " + sum);
        System.out.println("Average Age: " + average);
        System.out.println("\n== Calc New Style ==");
        long totalAge = personList.stream().
                filter(person -> person.getAge() >=23 && person.getAge()<=65).mapToInt(Person::getAge).sum();
        System.out.println(totalAge);
        OptionalDouble averageAge = personList.parallelStream()
                .filter(person -> person.getAge() >=23 && person.getAge()<=65).mapToDouble(Person::getAge).average();
        System.out.println(averageAge.isPresent()? averageAge.getAsDouble(): 0);
    }
    public static void runnableTest(){
        System.out.println("=== RunnableTest ===");
        Runnable r1 = new Runnable(){
            @Override
            public void run(){
                System.out.println("Hello world one!");
            }
        };
        r1.run();
        Runnable r2 = () -> System.out.println("Hello world two!");
        r2.run();
    }
    public static void comparatorTest(){
        List<Person> personList = Person.createShortList();
        Collections.sort(personList, new Comparator<Person>(){
            public int compare(Person p1, Person p2){
                return p1.getSurName().compareTo(p2.getSurName());
            }
        });
        System.out.println("=== sorted asc surName");
        for (Person p : personList) {
            p.printName();
        }
        //use lambda 
        System.out.println("=== sorted asc surName");
        Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName()));
        for (Person p :personList) {
            p.printName();
        }
        System.out.println("=== sorted desc surName");
        Collections.sort(personList, (p1, p2) -> p2.getSurName().compareTo(p1.getSurName()));
        for (Person p :personList) {
            p.printName();
        }
    }
    public static void functionTest(){
        List<Person> personlists  = Person.createShortList();
        Function<Person,String> westernStyle = p -> {
            return "\nName: " + p.getGivenName() + " " + p.getSurName() + "\n" +
            "Age: " + p.getAge() + "  " + "Gender: " + p.getGender() + "\n" +
            "EMail: " + p.geteMail() + "\n" +
            "Phone: " + p.getPhone() + "\n" +
            "Address: " + p.getAddress();
        };
        System.out.println("\n ===westernStyle=== ");
        for (Person p :personlists) {
            System.out.println(
             p.printCustom(westernStyle)
            );
        }
    }
}
class Person {
    private String givenName;
    private String surName;
    private int age;
    public void setGivenName(String givenName) {
        this.givenName = givenName;
    }
    public void setSurName(String surName) {
        this.surName = surName;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Gender getGender() {
        return gender;
    }
    public void setGender(Gender gender) {
        this.gender = gender;
    }
    public String geteMail() {
        return eMail;
    }
    public void seteMail(String eMail) {
        this.eMail = eMail;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    private Gender gender;
    private String eMail;
    private String phone;
    private String address;
    public static class Builder{
        private String givenName="";
        private String surName="";
        private int age = 0;
        private Gender gender = Gender.FEMALE;
        private String eMail = "";
        private String phone = "";
        private String address = "";
        public Person.Builder givenName(String givenName){
            this.givenName = givenName;
            return this;
        }
        public Person.Builder surName(String surName){
            this.surName = surName;
            return this;
        }
        public Person.Builder age (int val){
            age = val;
            return this;
        }
        public Person.Builder gender(Gender val){
            gender = val;
            return this;
        }
        public Person.Builder email(String val){
            eMail = val;
            return this;
        }
        public Person.Builder phoneNumber(String val){
            phone = val;
            return this;
        }
        public Person.Builder address(String val){
            address = val;
            return this;
        }
        public Person build(){
            return new Person(this);
        }
    }
    private Person(){
        super();
    }
    private Person(Person.Builder builder){
        givenName = builder.givenName;
        surName = builder.surName;
        age = builder.age;
        gender = builder.gender;
        eMail = builder.eMail;
        phone = builder.phone;
        address = builder.address;
    }
    public String getGivenName(){
        return givenName;
    }
    public String getSurName(){
        return surName;
    }
    public int getAge(){
        return age;
    }
    public void print(){
        System.out.println(
            "\nName: " + givenName + " " + surName + "\n" + 
            "Age: " + age + "\n" +
            "Gender: " + gender + "\n" + 
            "eMail: " + eMail + "\n" + 
            "Phone: " + phone + "\n" +
            "Address: " + address + "\n"
                                );
    } 
    public void printName(){    
        System.out.println(
            "Name: " + givenName + " " + surName);
    }
    @Override
    public String toString(){
        return "Name: " + givenName + " " + surName + "\n" + "Age: " + age + "  Gender: " + gender + "\n" + "eMail: " + eMail + "\n" + "Address: " + address + "\n";
    } 
    public static List<Person> createShortList(){
        List<Person> people = new ArrayList<>();
        people.add(
            new Person.Builder()
                        .givenName("Bob")
                        .surName("Baker")
                        .age(21)
                        .gender(Gender.MALE)
                        .email("bob.baker@example.com")
                        .phoneNumber("201-121-4678")
                        .address("44 4th St, Smallville, KS 12333")
                        .build() 
            );
        people.add(
            new Person.Builder()
                        .givenName("Jane")
                        .surName("Doe")
                        .age(25)
                        .gender(Gender.FEMALE)
                        .email("jane.doe@example.com")
                        .phoneNumber("202-123-4678")
                        .address("33 3rd St, Smallville, KS 12333")
                        .build() 
            );
        people.add(
            new Person.Builder()
                        .givenName("John")
                        .surName("Doe")
                        .age(25)
                        .gender(Gender.MALE)
                        .email("john.doe@example.com")
                        .phoneNumber("202-123-4678")
                        .address("33 3rd St, Smallville, KS 12333")
                        .build()
        );
        people.add(
            new Person.Builder()
                        .givenName("James")
                        .surName("Johnson")
                        .age(45)
                        .gender(Gender.MALE)
                        .email("james.johnson@example.com")
                        .phoneNumber("333-456-1233")
                        .address("201 2nd St, New York, NY 12111")
                        .build()
        );
        people.add(
            new Person.Builder()
                        .givenName("Joe")
                        .surName("Bailey")
                        .age(67)
                        .gender(Gender.MALE)
                        .email("joebob.bailey@example.com")
                        .phoneNumber("112-111-1111")
                        .address("111 1st St, Town, CA 11111")
                        .build()
        );
        people.add(
            new Person.Builder()
                        .givenName("Phil")
                        .surName("Smith")
                        .age(55)
                        .gender(Gender.MALE)
                        .email("phil.smith@examp;e.com")
                        .phoneNumber("222-33-1234")
                        .address("22 2nd St, New Park, CO 222333")
                        .build()
        );
        people.add(
            new Person.Builder()
                        .givenName("Betty")
                        .surName("Jones")
                        .age(85)
                        .gender(Gender.FEMALE)
                        .email("betty.jones@example.com")
                        .phoneNumber("211-33-1234")
                        .address("22 4th St, New Park, CO 222333")
                        .build()
        );
        return people;
    }
    public String printCustom(Function <Person, String> f){
        return f.apply(this);
    }
}
enum Gender { MALE, FEMALE }