import java.util.*;
import java.lang.*;
import java.util.stream.Stream;

class Rextester
{  
    public static void main(String args[])
    {
        System.out.println("Hello, World!");
        
        Comparator<Employee> sortByName = new Comparator<Employee>() {
            @Override
            public int compare(Employee e1, Employee e2) {
                return e1.getName().compareTo(e2.getName());
            }
        };
        
        Employee emp1 = new Employee(1, "Hatim", 12.12);
        Employee emp2 = new Employee(2, "El Ab", 14.14);
        
        int compareResult = sortByName.compare(emp1, emp2);
        System.out.println(compareResult);
        
        System.out.println("H".compareTo("E"));
        
        // define an interface reference and assign a lambda method instead of implementing the abstract method, 
        // then call the method by its name as defined in the interface 
        Comparator<Employee> sortByNameLambda = ((Employee e1, Employee e2) -> e1.getName().compareTo(e2.getName()));
        
        // here the call of the method compare of the interface Comparator<Employee>
        compareResult = sortByNameLambda.compare(emp1, emp2);
        System.out.println(compareResult);
        
        
        // Initial data
        ArrayList<Employee> list = new ArrayList<Employee>();

        list.add(new Employee(500, "Shifoo", 150000));
        list.add(new Employee(504, "Oogway", 120000));
        list.add(new Employee(503, "Tigress", 100000));
        list.add(new Employee(730, "Mantis", 45000));
        
        System.out.println("Initial List :");
        list.forEach(System.out::println);
        
        // Static sort method of the Collections class 
        Collections.sort(list, sortByName);
        System.out.println("\nStandard Sorted by Name :");
        list.forEach(System.out::println);
        
        list.sort(sortByNameLambda);
        System.out.println("\nLambda Sorted by Name :");
        list.forEach(System.out::println);
        
        System.out.println("\n#### Streams ####");
        
        String[] str_array = new String[]{"P", "A", "V"};
        //java.util.stream.Stream
        Stream<String> str_stream =
            Arrays
            .stream(str_array);
        
        str_stream.forEach(elem -> System.out.println(elem));
        
        List<String> str_list = Arrays.asList("AAA", "BBB", "CCC", "USW...");
        str_stream = str_list.stream();
        str_stream.forEach(System.out::println);
    
    }
}

class Employee {
    
    private int id;
    private String name;
    private double salary;

    public Employee(int id, String name, double salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }
    
    //Getters & Setters
    public String getName() {
        return this.name;
    }
    
    public String toString() {
        return this.getName();
    }
}