import java.util.*;

class superList  {

    public String get_class_name(Object o){
        String the_class=o.getClass().getCanonicalName();  //might be a package, for example student_type.athlete so ..
        return the_class.substring(the_class.indexOf(".")+1);
    }

    public void provide_information( Object o,String the_selector){
        switch (get_class_name(o)) {                               
        case "athlete" : {
                athlete s = (athlete) o ;
                if (s.sport.equals(the_selector))
                    System.out.println(s.name + " " + s.year + " " + s.testgrade + " " + s.sport);
                break;
            }
        case "student_worker" : {
                student_worker s = (student_worker) o;
                if (s.job.equals(the_selector))
                    System.out.println(s.name + " " + s.job);
                break;
            }
        case "student" : {
                if (the_selector.equals("student")) {
                    student s = (student) o;
                    System.out.println(s.name + " is just a student");
                }
                break;
            }
        case "graduate_student" : {
                /*  do nothing*/
                break;
            }
        default :{
                // do nothing
            }
        }
    }
    public void SelectWhereAll( List<? super student> l) {
        for (int i = 0; i < l.size(); i++) {
            System.out.println(((student)l.get(i)).name+"  "+l.get(i).getClass().getCanonicalName());  
        }
    }
    public void SelectWhereSelected( List<? super student> l,String the_selector) {
        for (Object o: l) {
            provide_information(o,the_selector);
        }
    }

    public static void main (String[] args){
        new superList( );
    }

    public superList() {
        student_worker sw=new student_worker("Lab. Assistant", "Sam Smith", "Freshman", 95);
        student_worker sw1=new student_worker("Dorm. Monitor", "Harry Smith", "Senior", 96);
        athlete ath = new athlete("Baseball", "Joe Johnson", "Sophomore", 90);
        athlete ath1 = new athlete("Football", "Joe Jones", "Senior", 83);
        athlete ath2 = new athlete("Football", "Harry Brown", "Senior", 90);
        student jj = new student("Robert Brown", "Sophomore", 80);
        graduate_student gs = new graduate_student("Computer Science", "Steven Jones", "Year 2", 80);
        List<? super student> test_list = new ArrayList<>();
        test_list.add(ath);
        test_list.add(jj);
        test_list.add(sw);
        test_list.add(sw1);
        test_list.add(ath1);
        test_list.add(ath2);
        test_list.add(gs);
        /* Object an_object=new Object();
         test_list.add(an_object)                         ;
          Error no suitable method found for add(Object);                                                ;
         String smith="hello";
          test_list.add(smith);
          Error no suitable method found for add(String);
           drop_out drop= new drop_out("Joe Java");
          test_list.add(drop);
          Error no suitable method found for add(drop_out);
          */
        System.out.println("//  Get the students");
        SelectWhereAll(test_list);
        System.out.println("___________________________________________\n");
        System.out.println("//  Now the  Baseball Players  ");
        SelectWhereSelected(test_list,"Baseball");
        //Another Version
        Iterator<? super student> itr = test_list.iterator();
        while (itr.hasNext()) {
            provide_information(itr.next(),"Baseball");
        }
        System.out.println("___________________________________________\n");
        System.out.println("//  Now the Football Players  ");
        SelectWhereSelected(test_list,"Football");
        System.out.println("___________________________________________\n");
        System.out.println("//  Now the Student Workers who are Lab. Assistants  ");
        SelectWhereSelected(test_list,"Lab. Assistant");
        System.out.println("___________________________________________\n");
        System.out.println("// Two Streams");
        test_list.stream()
        .filter((a)->get_class_name(a).equals("athlete"))
        .forEach((a)->System.out.println(((student)a).name));
        /////////////////////////////////////
        System.out.println("\nThe Football Players in order are");
        test_list.stream()
        .filter((a)->get_class_name(a).equals("athlete"))
        .map((a)->(athlete)a)
        .filter((a) -> a.sport.equals("Football"))
        .sorted((a, b) -> a.name.compareTo(b.name))
        .map((a)->a.name)
        .forEach(System.out::println);
    }
}
class student {
    public String name;
    public String year;     //Frosh, Soph, Jr, Senior,Year 1,Year 2,Year 3
    public int testgrade;   //entrance exam grade
    public student(String s,String y,int t){
        name=s;   year=y;   testgrade=t;
    }
}

class athlete extends student {
    public String sport;
    public athlete(String s,String n,String y,int t){
        super(n,y,t);
        sport=s;
    }
}

class graduate_student extends student {
    public String program;
    public graduate_student(String s,String n,String y,int t){
        super(n,y,t);
        program=s;
    }
}
class student_worker extends student {
    public String job;
    public student_worker(String s,String n,String y,int t){
        super(n,y,t);
        job=s;
    }
}
//A non-student
class drop_out {
    public String name;
    public drop_out(String s){    
        name=s;
    }
}